【问题标题】:Font scaling based on width of container基于容器宽度的字体缩放
【发布时间】:2021-05-30 03:25:01
【问题描述】:

我很难理解字体缩放。

我目前有一个网站,其正文 font-size 为 100%。 100% 是什么?这似乎计算为 16 像素。

我的印象是 100% 会以某种方式指代浏览器窗口的大小,但显然不是因为无论窗口被调整为移动宽度还是完整的宽屏桌面,它总是 16 像素。

如何使网站上的文本相对于其容器进行缩放?我尝试使用em,但这也无法扩展。

我的理由是,当你调整大小时,我的菜单之类的东西会被压扁,所以我需要减少与容器宽度相关的其他元素中的 px font-size.menuItem。 (例如,在大型桌面的菜单中,22px 完美运行。向下移动到平板电脑宽度,16px 更合适。)

我知道我可以添加断点,但我真的希望文本能够像具有额外断点一样以及缩放,否则,每减少 100 像素,我就会得到数百个断点控制文本的宽度。

【问题讨论】:

  • font-size: 100%; 表示文本大小的 100%(即它从其父级继承的大小)。默认情况下为 16 像素。所以如果你使用 50%,那就是 font-size: 8px
  • 您正在寻找的称为响应式或视口大小的排版。 css-tricks.com/viewport-sized-typography
  • FitText 看看。
  • @Andy:实际上,“默认”是用户将浏览器文本大小设置为的任何值,不一定会解析为 16px。

标签: css responsive-design font-size


【解决方案1】:

编辑:如果容器不是主体 CSS Tricks 涵盖了您在 Fitting Text to a Container 中的所有选项。

如果容器是body,你要找的是Viewport-percentage lengths

视口百分比长度initial containing block 的大小相关。当初始包含块的高度或宽度发生变化时,它们会相应地缩放。但是,当根元素的overflow值为auto时,任何滚动条都被假定为不存在。

值是:

  • vw(视口宽度的百分比)
  • vh(视口高度的百分比)
  • vi(根元素内联轴方向的视口大小的 1%)
  • vb(根元素块轴方向的视口大小的 1%)
  • vminvwvh 中较小的一个)
  • vmax(较大的或vwvh

1 v* 等于初始包含块的 1%。

使用它看起来像这样:

p {
    font-size: 4vw;
}

如您所见,当视口宽度增加时,font-size 也会增加,而无需使用媒体查询。

这些值是一个大小单位,就像pxem 一样,因此它们也可用于调整其他元素的大小,例如宽度、边距或内边距。

浏览器支持非常好,但您可能需要备用,例如:

p {
    font-size: 16px;
    font-size: 4vw;
}

查看支持统计:http://caniuse.com/#feat=viewport-units

另外,请查看 CSS-Tricks 以获得更广泛的外观:Viewport Sized Typography

这是一篇关于设置最小/最大尺寸和对尺寸进行更多控制的好文章:Precise control over responsive typography

还有一篇关于使用 calc() 设置大小以使文本填充视口的文章:http://codepen.io/CrocoDillon/pen/fBJxu

另外,请查看这篇文章,该文章也使用了一种称为“熔融前导”的技术来调整行高。 Molten Leading in CSS

【讨论】:

  • 但是如果容器不是视口(body)呢?
【解决方案2】:

但是如果容器不是视口(主体)呢?

Alex 在the accepted answer 下的评论中提出了这个问题。

这一事实并不意味着vw 在某种程度上不能用于确定该容器的大小。现在要看到任何变化,必须假设容器在某种程度上是灵活的。无论是通过直接百分比width 还是通过 100% 减去利润率。如果容器始终设置为 200px 宽,则该点变得“没有意义”——然后只需设置适用于该宽度的 font-size

示例 1

但是,对于灵活宽度的容器,必须意识到在某些方面容器仍然在视口之外调整大小。因此,需要根据与视口的百分比大小差异调整vw 设置,这意味着要考虑父包装器的大小。 Take this example:

div {
    width: 50%;
    border: 1px solid black;
    margin: 20px;
    font-size: 16px;
    /* 100 = viewport width, as 1vw = 1/100th of that
       So if the container is 50% of viewport (as here)
       then factor that into how you want it to size.
       Let's say you like 5vw if it were the whole width,
       then for this container, size it at 2.5vw (5 * .5 [i.e. 50%])
    */
    font-size: 2.5vw;
}

这里假设divbody 的子代,它是50%100% 宽度,这是基本情况下的视口大小。基本上,您想要设置一个看起来不错的vw。正如您在我对上述 CSS 内容的评论中看到的那样,您可以在数学上“思考”关于完整视口大小的问题,但您不需要 这样做。文本将随着容器“弯曲”,因为容器随着视口大小的调整而弯曲。更新:here's an example of two differently sized containers

示例 2

您可以通过强制基于此的计算来帮助确保视口大小。 Consider this example:

html {width: 100%;} /* Force 'html' to be viewport width */
body {width: 150%; } /* Overflow the body */

div {
    width: 50%;
    border: 1px solid black;
    margin: 20px;
    font-size: 16px;
    /* 100 = viewport width, as 1vw = 1/100th of that
       Here, the body is 150% of viewport, but the container is 50%
       of viewport, so both parents factor  into how you want it to size.
       Let's say you like 5vw if it were the whole width,
       then for this container, size it at 3.75vw
       (5 * 1.5 [i.e. 150%]) * .5 [i.e. 50%]
    */
    font-size: 3.75vw;
}

大小仍然基于视口,但本质上是基于容器大小本身设置的。

容器的大小是否应该动态变化...

如果容器元素的大小最终通过@media 断点或通过 JavaScript 动态改变其百分比关系,那么无论基本“目标”是什么,都需要重新计算以保持文本大小的相同“关系”。

以上面的示例 #1 为例。如果div 通过@media 或JavaScript 切换到25% 宽度,那么同时,font-size 需要在媒体查询或通过JavaScript 中调整为5vw * .25 = 1.25 的新计算.这将使文本大小与原始 50% 容器的“宽度”从视口大小减少一半时的大小相同,但现在由于其自身百分比计算的变化而减小。

挑战

使用the CSS3 calc() function,动态调整将变得困难,因为此时该功能不适用于font-size。因此,如果您的宽度在 calc() 上发生变化,则无法进行纯 CSS 3 调整。当然,对边距宽度的细微调整可能不足以保证 font-size 的任何更改,因此可能无关紧要。

【讨论】:

  • 很好的答案,但是,如果包含元素具有最大宽度,它将不起作用。
【解决方案3】:

SVG 解决方案:

.resizeme {
  resize: both;
  margin: 0;
  padding: 0;
  height: 75px;
  width: 500px;
  background-color: lightblue;
  overflow: hidden;
}
<div class="resizeme">
  <svg
    width="100%"
    height="100%"
    viewBox="0 0 500 75"
    preserveAspectRatio="xMinYMid meet"
    style="background-color:green"
    xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink"
  >
        <text
          x="0"
          y="75"
          font-size="75"
          fill="black"
        >█Resize This█</text>
      </svg>
</div>

使用 foreignObject 进行 SVG 和文本换行的解决方案:

.resizeme {
  resize: both;
  margin: 0;
  padding: 0;
  height: 200px;
  width: 500px;
  background-color: lightblue;
  overflow: hidden;
}
<div class="resizeme">
  <svg
    width="100%"
    height="100%"
    viewBox="0 0 500 200"
    preserveAspectRatio="xMinYMin meet"
  >
      <foreignObject width="100%" height="100%" xmlns="http://www.w3.org/1999/xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml" style="background-color:lightgreen;">
          <h1>heading</h1>
          <p>Resize the blue box.</p>
        </div>
      </foreignObject>
    </svg>
</div>

【讨论】:

  • 救命!!!!
  • 我不知道为什么,但这就是行不通。这里的 sn-p 有效,但是传输这个 elsewear 和文本只是溢出 SVG 容器而不改变大小。
【解决方案4】:

在我的一个项目中,我使用 vw 和 vh 之间的“混合”来根据我的需要调整字体大小,例如:

font-size: calc(3vw + 3vh);

我知道这并不能回答 OP 的问题,但也许它可以成为其他任何人的解决方案。

【讨论】:

  • 这就是我所说的优雅解决方案!
【解决方案5】:

带有calc()、CSS 单元和数学的纯 CSS 解决方案

这正是 OP 所要求的,但可能会让某人开心。这个答案并不容易,需要在开发人员端进行一些研究。

我终于得到了一个纯 CSS 解决方案,使用 calc() 和不同的单位。您需要对公式有一些基本的数学理解才能计算出calc() 的表达式。

当我解决这个问题时,我必须得到一个全页宽度的响应式标题,并在 DOM 中填充一些父级。我将在这里使用我的值,用你自己的值替换它们。

数学

你需要:

  • 在某些视口中很好地调整了比例。我使用了 320 像素,因此我得到了 24 像素高和 224 像素宽,所以比例是 9.333... 或 28 / 3
  • 容器的宽度,我有padding: 3em 和全宽,所以这是100wv - 2 * 3em

X 是容器的宽度,所以用你自己的表达式替换它或调整值以获得整页文本。 R 是您将拥有的比率。您可以通过调整某些视口中的值、检查元素的宽度和高度并用您自己的值替换它们来获得它。另外,它是width / heigth ;)

x = 100vw - 2 * 3em = 100vw - 6em
r = 224px/24px = 9.333... = 28 / 3

y = x / r
  = (100vw - 6em) / (28 / 3)
  = (100vw - 6em) * 3 / 28
  = (300vw - 18em) / 28
  = (75vw - 4.5rem) / 7

然后砰!有效!我写了

font-size: calc((75vw - 4.5rem) / 7)

到我的标题,它在每个视口中都调整得很好。

但它是如何工作的呢?

我们需要一些常量。 100vw 表示视口的全宽,我的目标是建立带有一些填充的全宽标题。

比率。在一个视口中获得宽度和高度让我可以使用比率,并且通过比率我知道在其他视口宽度中的高度应该是多少。手动计算它们会花费大量时间,并且至少会占用大量带宽,因此这不是一个好的答案。

结论

我想知道为什么没有人知道这一点,有些人甚至说这不可能用 CSS 来修补。我不喜欢在调整元素时使用 JavaScript,所以我不接受 JavaScript(忘记 jQuery)的答案,而无需深入挖掘。总而言之,很好地解决了这个问题,这是在网站设计中实现纯 CSS 的一步。

对于我的文本中的任何不寻常的约定,我深表歉意,我不是英语母语人士,而且对编写 StackOverflow 答案也很陌生。

还应该注意的是,我们在某些浏览器中有邪恶的滚动条。例如,在使用 Firefox 时,我注意到 100vw 表示视口的全宽,在滚动条下延伸(内容无法展开!),因此全宽文本必须仔细设置边距,最好在许多浏览器和设备上进行测试。

【讨论】:

  • 此解决方案仅在以下情况下有效:(1) 您知道字体,(2) 字体在用户设备上可用,以及 (3) 文本始终相同。这使它成为一个非常有限的用例。
【解决方案6】:

这个问题有一个很大的哲学。

最简单的做法是给 body 指定一定的字体大小(我推荐 10),然后所有其他元素的字体都将是 emrem。 我会给你一个例子来理解这些单位。 Em 总是相对于它的父级:

body{font-size: 10px;}
.menu{font-size: 2em;} /* That means 2*10 pixels  = 20 pixels */
.menu li{font-size: 1.5em;} /* That means 1.5*20 pixels = 30 pixels */

Rem 总是相对于 body:

body{font-size: 10px;}
.menu{font-size: 2rem;} /* That means 2*10 pixels = 20 pixels */
.menu li{font-size: 1.5rem;} /* that means 1.5*10 pixels = 15 pixels */

然后您可以创建一个脚本来修改相对于您的容器宽度的字体大小。 但这不是我推荐的。因为例如在一个 900 像素宽度的容器中,您将拥有一个具有 12 像素字体大小的 p 元素。根据您的想法,这将成为一个 300 像素宽、4 像素字体大小的容器。必须有一个下限。

其他解决方案是使用媒体查询,以便您可以设置不同宽度的字体。

但我推荐的解决方案是使用可以帮助您解决此问题的 JavaScript 库。还有我目前发现的fittext.js

【讨论】:

    【解决方案7】:

    函数如下:

    document.body.setScaledFont = function(f) {
      var s = this.offsetWidth, fs = s * f;
      this.style.fontSize = fs + '%';
      return this
    };
    

    然后将所有文档子元素字体大小转换为em's 或%

    然后在代码中添加类似这样的内容来设置基本字体大小。

    document.body.setScaledFont(0.35);
    window.onresize = function() {
        document.body.setScaledFont(0.35);
    }
    

    http://jsfiddle.net/0tpvccjt/

    【讨论】:

      【解决方案8】:

      有一种方法可以做到这一点没有 JavaScript!

      您可以使用内联 SVG 图像。如果它是内联的,您可以在 SVG 上使用 CSS。您必须记住,使用此方法意味着您的 SVG 图像将响应其容器大小。

      尝试使用以下解决方案...

      HTML

      <div>
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360.96 358.98" >
            <text>SAVE $500</text>
        </svg>
      </div>
      

      CSS

      div {
        width: 50%; /* Set your container width */
        height: 50%; /* Set your container height */
      
      }
      
      svg {
        width: 100%;
        height: auto;
      
      }
      
      text {
        transform: translate(40px, 202px);
        font-size: 62px;
        fill: #000;
      }
      

      示例: https://jsfiddle.net/k8L4xLLa/32/

      想要更华丽的东西吗?

      SVG 图像还允许您使用形状和垃圾来做很酷的事情。看看这个可扩展文本的绝佳用例...

      https://jsfiddle.net/k8L4xLLa/14/

      【讨论】:

        【解决方案9】:

        这可能不是超级实用,但是如果您希望字体成为父级的直接函数,而不需要任何 JavaScript 侦听/循环(间隔)来读取 div/page 的大小,有一种方法去做吧。 iframe。

        iframe 中的任何内容都会将 iframe 的大小视为视口的大小。所以诀窍是只制作一个 iframe,其宽度是您希望文本的最大宽度,其高度等于最大高度 * 特定文本的纵横比。

        抛开视口单位不能同时出现在文本的父单位旁边的限制(例如,让 % 大小的行为与其他所有人一样),视口单位确实提供了一个非常强大的工具:能够获得最小值/最大维度。你不能在其他任何地方这样做 - 你不能说......让这个 div 的高度成为父 * 东西的宽度。

        话虽如此,诀窍是使用 vmin,并设置 iframe 大小,以便当高度为限制尺寸时 [fraction] * total height 是一个好的字体大小,而当宽度是限制尺寸。这就是为什么高度必须是宽度和纵横比的乘积。

        对于我的特定示例,您有

        .main iframe{
          position: absolute;
          top: 50%;
          left: 50%;
          width: 100%;
          height: calc(3.5 * 100%);
          background: rgba(0, 0, 0, 0);
          border-style: none;
          transform: translate3d(-50%, -50%, 0);
        }
        

        这种方法的小烦恼是您必须手动设置 iframe 的 CSS。如果附加整个 CSS 文件,则会占用许多文本区域的大量带宽。所以,我要做的是直接从我的 CSS 中附加我想要的规则。

        var rule = document.styleSheets[1].rules[4];
        var iDoc = document.querySelector('iframe').contentDocument;
        iDoc.styleSheets[0].insertRule(rule.cssText);
        

        您可以编写小函数来获取 CSS 规则/所有会影响文本区域的 CSS 规则。

        如果没有一些循环/监听 JavaScript,我想不出另一种方法来做到这一点。真正的解决方案是让浏览器提供一种方法来根据父容器来缩放文本以提供相同的 vmin/vmax 类型功能。

        JSFiddle: https://jsfiddle.net/0jr7rrgm/3/ (单击一次将红色方块锁定到鼠标,再次单击释放)

        小提琴中的大部分 JavaScript 只是我的自定义点击拖动功能。

        【讨论】:

          【解决方案10】:

          使用vwem & co。确实有效,但 IMO 它总是需要人工进行微调。

          这是我刚刚根据@tnt-rox' answer 编写的一个脚本,它试图使人类的触摸自动化:

          $('#controller').click(function(){
              $('h2').each(function(){
                  var
                      $el = $(this),
                      max = $el.get(0),
                      el = null
                  ;
                  max =
                      max
                      ? max.offsetWidth
                      : 320
                  ;
                  $el.css({
                      'font-size': '1em',
                      'display': 'inline',
                  });
                  el = $el.get(0);
          
                  el.get_float = function(){
                      var
                          fs = 0
                      ;
                      if (this.style && this.style.fontSize) {
                          fs = parseFloat(this.style.fontSize.replace(/([\d\.]+)em/g, '$1'));
                      }
                      return fs;
                  };
          
                  el.bigger = function(){
                      this.style.fontSize = (this.get_float() + 0.1) + 'em';
                  };
          
                  while (el.offsetWidth < max) {
                      el.bigger();
                  }
          
                  // Finishing touch.
                  $el.css({
                      'font-size': ((el.get_float() -0.1) +'em'),
                      'line-height': 'normal',
                      'display': '',
                  });
              });  // end of (each)
          });    // end of (font scaling test)
          div {
            width: 50%;
            background-color: tomato;
            font-family: 'Arial';
          }
          
          h2 {
            white-space: nowrap;
          }
          
          h2:nth-child(2) {
            font-style: italic;
          }
          <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
          <input type="button" id="controller" value="Apply" />
          <div>
            <h2>Lorem ipsum dolor</h2>
            <h2>Test String</h2>
            <h2>Sweet Concatenation</h2>
            <h2>Font Scaling</h2>
          </div>

          它基本上将字体大小减小到1em,然后开始增加 0.1 直到达到最大宽度。

          JSFiddle

          【讨论】:

            【解决方案11】:

            100% 是相对于基本字体大小的,如果您没有设置它,它将是浏览器的用户代理默认值。

            为了获得您想要的效果,我会使用一段 JavaScript 代码来调整相对于窗口尺寸的基本字体大小。

            【讨论】:

              【解决方案12】:

              使用 CSS 变量

              还没有人提到 CSS 变量,这种方法对我来说效果最好,所以:

              假设您的页面上有一个列,它是移动用户屏幕宽度的 100%,但 max-width 为 800 像素,因此在桌面上,该列的两侧都有一些空间。将其放在页面顶部:

              <script> document.documentElement.style.setProperty('--column-width', Math.min(window.innerWidth, 800)+'px'); </script>
              

              现在您可以使用该变量(而不是内置的vw 单位)来设置字体的大小。例如

              p {
                font-size: calc( var(--column-width) / 100 );
              }
              

              这不是一个 CSS 方法,但它非常接近。

              【讨论】:

              • 如果您需要从 js 操作它,这实际上是一个很好的解决方案 - 谢谢!
              • 这很酷,但我认为它不能响应式地工作,setProperty 只会运行一次对吗?
              【解决方案13】:

              我自己的基于 jQuery 的解决方案通过逐渐增加字体大小来工作,直到容器高度大幅增加(意味着它有一个换行符)。

              它非常简单,但效果很好,而且非常易于使用。您不必了解所使用字体的任何信息,一切都由浏览器处理。

              你可以在http://jsfiddle.net/tubededentifrice/u5y15d0L/2/上玩它

              魔法发生在这里:

              var setMaxTextSize=function(jElement) {
                  // Get and set the font size into data for reuse upon resize
                  var fontSize=parseInt(jElement.data(quickFitFontSizeData)) || parseInt(jElement.css("font-size"));
                  jElement.data(quickFitFontSizeData, fontSize);
              
                  // Gradually increase font size until the element gets a big increase in height (i.e. line break)
                  var i = 0;
                  var previousHeight;
                  do
                  {
                      previousHeight=jElement.height();
                      jElement.css("font-size", "" + (++fontSize) + "px");
                  }
                  while(i++ < 300 && jElement.height()-previousHeight < fontSize/2)
              
                  // Finally, go back before the increase in height and set the element as resized by adding quickFitSetClass
                  fontSize -= 1;
                  jElement.addClass(quickFitSetClass).css("font-size", "" + fontSize + "px");
              
                  return fontSize;
              };
              

              【讨论】:

                【解决方案14】:

                从艺术角度来说,如果您需要在相同宽度内放置两行或多行文本,而不管它们的字符数如何,那么您有不错的选择。

                最好找到一个动态的解决方案,这样无论输入什么文本,我们都会得到一个很好的显示。

                让我们看看我们如何接近。

                var els     = document.querySelectorAll(".divtext"),
                refWidth    = els[0].clientWidth,
                refFontSize = parseFloat(window.getComputedStyle(els[0],null)
                                               .getPropertyValue("font-size"));
                
                els.forEach((el,i) => el.style.fontSize = refFontSize * refWidth / els[i].clientWidth + "px")
                #container {
                  display: inline-block;
                  background-color: black;
                  padding: 0.6vw 1.2vw;
                }
                .divtext {
                  display: table;
                  color: white;
                  font-family: impact;
                  font-size: 4.5vw;
                }
                <div id="container">
                  <div class="divtext">THIS IS JUST AN</div>
                  <div class="divtext">EXAMPLE</div>
                  <div class="divtext">TO SHOW YOU WHAT</div>
                  <div class="divtext">YOU WANT</div>
                </div>

                我们所做的只是获取第一行的宽度(els[0].clientWidth)和字体大小(parseFloat(window.getComputedStyle(els[0],null).getPropertyValue("font-size")))作为参考,然后相应地计算后续行的字体大小。

                【讨论】:

                  【解决方案15】:

                  在您的 CSS 中,尝试将其添加到底部以更改 320 像素的宽度,以便您的设计开始中断:

                  @media only screen and (max-width: 320px) {
                    body { font-size: 1em; }
                  }
                  

                  然后根据需要在“px”或“em”中指定字体大小。

                  【讨论】:

                    【解决方案16】:

                    This web component 更改字体大小,使内部文本宽度与容器宽度匹配。检查demo

                    你可以这样使用它:

                    <full-width-text>Lorem Ipsum</full-width-text>
                    

                    【讨论】:

                      【解决方案17】:

                      试试http://simplefocus.com/flowtype/。这就是我用于我的网站的方法,并且效果很好。

                      【讨论】:

                        【解决方案18】:

                        您可能正在寻找类似的东西:

                        http://jsfiddle.net/sijav/dGsC9/4/
                        http://fiddle.jshell.net/sijav/dGsC9/4/show/

                        我使用过flowtype,它运行良好(不过它是 JavaScript 而非纯 CSS 解决方案):

                        $('body').flowtype({
                            minFont: 10,
                            maxFont: 40,
                            minimum: 500,
                            maximum: 1200,
                            fontRatio: 70
                        });
                        

                        【讨论】:

                          【解决方案19】:

                          我已经准备了一个使用 CSS 变换而不是字体大小的简单缩放函数。您可以在任何容器内使用它,您不必设置媒体查询等。:)

                          博文: Full width CSS & JS scalable header

                          代码:

                          function scaleHeader() {
                            var scalable = document.querySelectorAll('.scale--js');
                            var margin = 10;
                            for (var i = 0; i < scalable.length; i++) {
                              var scalableContainer = scalable[i].parentNode;
                              scalable[i].style.transform = 'scale(1)';
                              var scalableContainerWidth = scalableContainer.offsetWidth - margin;
                              var scalableWidth = scalable[i].offsetWidth;
                              scalable[i].style.transform = 'scale(' + scalableContainerWidth / scalableWidth + ')';
                              scalableContainer.style.height = scalable[i].getBoundingClientRect().height + 'px';
                            }
                          }
                          

                          工作演示: https://codepen.io/maciejkorsan/pen/BWLryj

                          【讨论】:

                          • 我认为 OP 正在寻找 CSS 解决方案。
                          【解决方案20】:

                          我的问题类似,但与标题中的文本缩放有关。我尝试了 Fit Font,但我需要切换压缩器以获得任何结果,因为它解决了一个稍微不同的问题,Text Flow 也是如此。

                          所以我写了我自己的小插件来减小字体大小以适应容器,假设你有overflow: hiddenwhite-space: nowrap这样即使将字体减小到最小也不允许显示完整的标题,它只是切断它可以显示的内容。

                          (function($) {
                          
                            // Reduces the size of text in the element to fit the parent.
                            $.fn.reduceTextSize = function(options) {
                              options = $.extend({
                                minFontSize: 10
                              }, options);
                          
                              function checkWidth(em) {
                                var $em = $(em);
                                var oldPosition = $em.css('position');
                                $em.css('position', 'absolute');
                                var width = $em.width();
                                $em.css('position', oldPosition);
                                return width;
                              }
                          
                              return this.each(function(){
                                var $this = $(this);
                                var $parent = $this.parent();
                                var prevFontSize;
                                while (checkWidth($this) > $parent.width()) {
                                  var currentFontSize = parseInt($this.css('font-size').replace('px', ''));
                                  // Stop looping if min font size reached, or font size did not change last iteration.
                                  if (isNaN(currentFontSize) || currentFontSize <= options.minFontSize ||
                                      prevFontSize && prevFontSize == currentFontSize) {
                                    break;
                                  }
                                  prevFontSize = currentFontSize;
                                  $this.css('font-size', (currentFontSize - 1) + 'px');
                                }
                              });
                            };
                          })(jQuery);
                          

                          【讨论】:

                            【解决方案21】:

                            尝试使用fitText 插件,因为视口大小不是解决此问题的方法。

                            只需添加库:

                            <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
                            

                            并通过设置文本系数来更改字体大小:

                            $("#text_div").fitText(0.8);
                            

                            您可以设置文本的最大值和最小值:

                            $("#text_div").fitText(0.8, { minFontSize: '12px', maxFontSize: '36px' });
                            

                            【讨论】:

                              【解决方案22】:

                              始终让您的 元素 具有此属性:

                              JavaScript:element.style.fontSize = "100%";

                              CSS:style = "font-size: 100%;"

                              当您进入全屏模式时,您应该已经计算了一个 scale 变量(scale > 1 或 scale = 1)。然后,全屏:

                              document.body.style.fontSize = (scale * 100) + "%";
                              

                              用很少的代码就能很好地工作。

                              【讨论】:

                                【解决方案23】:

                                看看我的代码。它使font size smaller 变为fit 任何地方。

                                但我认为这不会带来良好的用户体验

                                var containerWidth = $("#ui-id-2").width();
                                var items = $(".quickSearchAutocomplete .ui-menu-item");
                                var fontSize = 16;
                                
                                items.each(function(){
                                    // Displaying a value depends sometimes on your case. You may make it block or inline-table instead of inline-block or whatever value that make the div take overflow width.
                                    $(this).css({"whiteSpace": "nowrap", "display": "inline-block"});
                                    while ($(this).width() > containerWidth){
                                         console.log("$(this).width()" + $(this).width() + "containerWidth" + containerWidth)
                                         $(this).css("font-size", fontSize -= 0.5);
                                    }
                                });
                                

                                【讨论】:

                                  【解决方案24】:

                                  对于动态文本,这个插件还是蛮有用的:

                                  http://freqdec.github.io/slabText/

                                  只需添加 CSS:

                                  .slabtexted .slabtext
                                  {
                                      display: -moz-inline-box;
                                      display: inline-block;
                                      white-space: nowrap;
                                  }
                                  .slabtextinactive .slabtext
                                  {
                                      display: inline;
                                      white-space: normal;
                                      font-size: 1em !important;
                                      letter-spacing: inherit !important;
                                      word-spacing: inherit !important;
                                      *letter-spacing: normal !important;
                                      *word-spacing: normal !important;
                                  }
                                  .slabtextdone .slabtext
                                  {
                                      display: block;
                                  }
                                  

                                  还有脚本:

                                  $('#mydiv').slabText();
                                  

                                  【讨论】:

                                    【解决方案25】:

                                    这对我有用:

                                    我尝试根据设置 `font-size: 10px` 得到的宽度/高度来近似字体大小。基本上,这个想法是“如果我有 20 像素宽度和 11 像素高度且 `font-size: 10px`,那么计算一个 50 像素宽度和 30 像素高度的容器的最大字体大小是多少?”

                                    答案是双比例系统:

                                    { 20:10=50:X, 11:10=30:Y } = { X= (10*50)/20, Y= (10*30)/11 }

                                    现在 X 是匹配宽度的字体大小,Y 是匹配高度的字体大小;取最小值

                                    function getMaxFontSizeApprox(el){
                                        var fontSize = 10;
                                        var p = el.parentNode;
                                    
                                        var parent_h = p.offsetHeight ? p.offsetHeight : p.style.pixelHeight;
                                        if(!parent_h)
                                            parent_h = 0;
                                    
                                        var parent_w = p.offsetHeight ? p.offsetWidth : p.style.pixelWidth;
                                        if(!parent_w)
                                            parent_w = 0;
                                    
                                        el.style.fontSize = fontSize + "px";
                                    
                                        var el_h = el.offsetHeight ? el.offsetHeight : el.style.pixelHeight;
                                        if(!el_h)
                                            el_h = 0;
                                    
                                        var el_w = el.offsetHeight ? el.offsetWidth : el.style.pixelWidth;
                                        if(!el_w)
                                            el_w = 0;
                                    
                                        // 0.5 is the error on the measure that JavaScript does
                                        // if the real measure had been 12.49 px => JavaScript would have said 12px
                                        // so we think about the worst case when could have, we add 0.5 to 
                                        // compensate the round error
                                        var fs1 = (fontSize*(parent_w + 0.5))/(el_w + 0.5);
                                        var fs2 = (fontSize*(parent_h) + 0.5)/(el_h + 0.5);
                                    
                                        fontSize = Math.floor(Math.min(fs1,fs2));
                                        el.style.fontSize = fontSize + "px";
                                        return fontSize;
                                    }
                                    

                                    注意:函数的参数必须是 span 元素或小于其父元素的元素,否则如果子元素和父元素具有相同的宽度/高度,函数将失败。

                                    【讨论】:

                                      【解决方案26】:

                                      HTML

                                      <div style="height:100px; width:200px;">
                                        <div id='qwe'>
                                          test
                                        </div>
                                      </div>
                                      

                                      最大化字体大小的 JavaScript 代码:

                                      var fontSize, maxHeight, maxWidth, textElement, parentElement;
                                      textElement = document.getElementById('qwe');
                                      parentElement = textElement.parentElement;    
                                      maxHeight = parentElement.clientHeight;
                                      maxWidth = parentElement.clientWidth;
                                      fontSize = maxHeight;
                                      var minFS = 3, maxFS = fontSize;
                                      while (fontSize != minFS) {
                                        textElement.style.fontSize = `${fontSize}px`;
                                        if (textElement.offsetHeight < maxHeight && textElement.offsetWidth <= maxWidth) {
                                          minFS = fontSize;
                                        } else{
                                          maxFS = fontSize;
                                        }
                                        fontSize = Math.floor((minFS + maxFS)/2);
                                      }
                                      textElement.style.fontSize = `${minFS}px`;
                                      

                                      【讨论】:

                                        【解决方案27】:

                                        我非常沮丧地尝试实现类似紧凑的文本换行,因此我最终使用了一种基于画布的方法,但没有成功尝试其他方法。我的目标看起来像附件,结果(对我来说)非常困难。希望有一天我们会有一种简单的纯 CSS 方式来做这件事。这种方法的缺点是文本被视为更像图像,但对于某些用例来说这很好。

                                        https://codesandbox.io/s/create-a-canvas-tightly-holding-a-word-st2h1?file=/index.html

                                        此图像是四个全出血画布的 CSS 网格布局的屏幕截图。

                                        【讨论】:

                                        • 不是一个真正的答案,而是我分享的一种感觉。
                                        • 有时文本只需要适合给定的空间。就像在现实世界中一样,商店的名称需要尽可能大地放在商店上。不要根据可用的字体/字体大小和商店宽度来命名商店。
                                        • 只想说我挖掘了你的艺术方向感。颜色、排版选择、并置......太棒了。
                                        【解决方案28】:

                                        作为 JavaScript 后备(或您唯一的解决方案),您可以使用我的 jQuery Scalem plugin,它允许您通过传递 reference 选项相对于父元素(容器)进行缩放。

                                        【讨论】:

                                          【解决方案29】:

                                          如果它对任何人都有帮助,这个线程中的大多数解决方案都是将文本换成多行,形式 e。

                                          但后来我发现了这个,并且成功了:

                                          https://github.com/chunksnbits/jquery-quickfit

                                          示例用法:

                                          $('.someText').quickfit({max:50,tolerance:.4})

                                          【讨论】:

                                            【解决方案30】:

                                            我没有看到任何关于 CSS flex 属性的答案,但它也非常有用。

                                            【讨论】:

                                            • 你能详细说明吗?
                                            猜你喜欢
                                            • 1970-01-01
                                            • 2018-04-26
                                            • 2016-08-17
                                            • 2021-02-13
                                            • 2014-01-05
                                            • 1970-01-01
                                            • 2020-02-15
                                            相关资源
                                            最近更新 更多