【问题标题】:Pure CSS to make font-size responsive based on dynamic amount of characters纯 CSS 根据动态字符数量使字体大小响应
【发布时间】:2013-01-04 01:56:44
【问题描述】:

我知道这可以通过 Javascript 轻松解决,但我只对纯 CSS 解决方案感兴趣。

我想要一种动态调整文本大小的方法,以便它始终适合固定的 div。这是示例标记:

<div style="width: 200px; height: 1em; overflow: hidden;">
  <p>Some sample dynamic amount of text here</p>
</div>

我在想,也许这可以通过在 ems 中指定容器的宽度,并让 font-size 继承该值来实现?

【问题讨论】:

  • 哇,等等。在ems 中指定width 则相反。 width 依赖于 font-size。 @JosephSilber 这正是我的想法。
  • 我很好奇这个问题。使用纯 css 解决方案而不是编写简单的 javascript 函数的驱动力是什么?
  • 驱动只是因为问题存在,纯CSS解决方案会很棒。考虑一下仅应用几种样式并知道您的动态内容永远不会破坏设计的可能性。
  • 万一有人偶然发现这个问题并且不介意使用JS,这里有一个插件fittextjs.com
  • fitText 有限制。例如,我只想在宽度超过 500 像素左右的小屏幕上运行它,我不希望我的标题再爆炸。这需要编写更多的 JavaScript。当您使用 JavaScript 进行布局时,关注点分离会很快失效。它绝不仅仅是一个快速的班轮。

标签: css


【解决方案1】:

为什么不根据字符数在服务器端设置类?

    .NotMuchText {
        font-size: 20px;
    }

    .LotsOfText {
        font-size: 10px;
    }

我还想要一个非 javascript 解决方案,CSS 解决方案,并改用 PHP/CSS 解决方案。

【讨论】:

    【解决方案2】:

    我是这样使用的:

    1.style.fontSize = 15.6/(document.getElementById("2").innerHTML.length)+ 'vw'

    其中:1 - 父 div Id 和 2 - 带有我的文本的 div 的 ID

    【讨论】:

    • 这不是 CSS。问题清楚地表明,使用 Javascript 很容易,但只寻找纯 CSS 解决方案。
    • 我知道,我浪费了很多时间在 CSS 中解决它,但是 ve foud it the easiest way to do so. Im 在 Stackoverflow 中是新手,所以没有t mention that its 用于纯 CSS 主题。下次我会尝试更多的presize。感谢您的反馈
    【解决方案3】:

    如果在Bootstrap 4从头开始做

    1. 转到https://bootstrap.build/app
    2. 点击搜索模式
    3. 搜索 $enable-responsive-font-sizes 并将其打开。
    4. 点击导出主题以保存您的自定义引导 CSS 文件。

    【讨论】:

    • 这在 Bootstrap 5 中默认启用,需要使用 RFS。
    【解决方案4】:

    编辑:注意attr()它与css中的calc()有关。将来你也许可以实现它。

    不幸的是,目前还没有唯一的 CSS 解决方案。这是我建议你做的。给你的元素一个标题属性。并使用文本溢出省略号来防止破坏设计并让用户知道那里有更多文本。

    <div style="width: 200px; height: 1em; text-overflow: ellipsis;" title="Some sample dynamic amount of text here">
     Some sample dynamic amount of text here
    </div>
    
    

    .

    .

    .

    或者,如果您只想根据视口缩小尺寸。 CSS3 支持与视口相关的新尺寸。

    body {
       font-size: 3.2vw;
    }
    
    1. 3.2vw = 视口宽度的 3.2%
    2. 3.2vh = 视口高度的 3.2%
    3. 3.2vmin = 3.2vw 或 3.2vh 中的较小值
    4. 3.2vmax = 3.2vw 或 3.2vh 中的较大者 见css-tricks.com/....,也见caniuse.com/....

    【讨论】:

    • 问题是关于相对于容器而不是整个视口的缩放。
    • ...问题是关于基于字符数量的缩放
    【解决方案5】:

    注意:此解决方案会根据视口大小而不是内容量而变化

    我刚刚发现使用大众汽车可以做到这一点。它们是与设置视口宽度相关的单位。有一些缺点,例如缺乏对旧版浏览器的支持,但这绝对是要认真考虑使用的东西。此外,您仍然可以为旧版浏览器提供后备功能,如下所示:

    p {
        font-size: 30px;
        font-size: 3.5vw;
    }
    

    http://css-tricks.com/viewport-sized-typography/https://medium.com/design-ux/66bddb327bb1

    【讨论】:

    • 会为此放弃 2 个 ups。胜利的 CSS 解决方案!
    • 专业提示:您可以通过执行font-size:calc(100% + 2vw); 或类似操作来防止文本变得太小并获得一些控制权。有点像min-font-size。浏览器对calc 的支持类似于vw
    • 赞成,但现在我想知道这是否真的回答了最初的问题。我的理解是您的文本长度是动态的,并且您希望更改字体大小以始终适合您的 div (200px) 的宽度。这如何解决这个问题?
    • 我同意@Floremin 的观点。这会根据视口宽度/高度缩放所有字体大小,而不是文本宽度/高度的容器。
    • @Floremin 是对的,这并不能解决问题。这会将字体大小计算为容器宽度的函数,而不是字符串长度的函数,因为它与容器宽度有关
    【解决方案6】:

    作为参考,非 CSS 解决方案:

    下面是一些 JS,它根据容器内的文本长度重新调整字体大小。

    Codepen 代码稍作修改,但思路与以下相同:

    function scaleFontSize(element) {
        var container = document.getElementById(element);
    
        // Reset font-size to 100% to begin
        container.style.fontSize = "100%";
    
        // Check if the text is wider than its container,
        // if so then reduce font-size
        if (container.scrollWidth > container.clientWidth) {
            container.style.fontSize = "70%";
        }
    }
    

    对我来说,当用户在下拉菜单中进行选择时,我调用此函数,然后我的菜单中的 div 被填充(这是我出现动态文本的地方)。

        scaleFontSize("my_container_div");
    

    此外,我还使用 CSS 省略号(“...”)来截断甚至 更长 的文本,如下所示:

    #my_container_div {
        width: 200px; /* width required for text-overflow to work */
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    

    所以,最终:

    • 短文本: 例如“苹果”

      完全渲染,漂亮的大字母。

    • 长文本: 例如“苹果和橘子”

      通过上述 JS 缩放功能,缩小 70%。

    • 超长文本: 例如“苹果、橙子和香蕉……”

      通过上述 JS 缩放函数和 CSS 规则,缩小 70% 并用“...”省略号截断。

    您还可以探索使用 CSS 字母间距来使文本更窄,同时保持相同的字体大小。

    【讨论】:

    • 因为用户要求纯 CSS 解决方案而被否决
    【解决方案7】:

    创建一个查找表,根据 &lt;div&gt; 中的字符串长度计算字体大小。

    const fontSizeLookupTable = () => {
      // lookup table looks like: [ '72px', ..., '32px', ..., '16px', ..., ]
      let a = [];
      // adjust this based on how many characters you expect in your <div>
      a.length = 32;
      // adjust the following ranges empirically
      a.fill( '72px' ,     );
      a.fill( '32px' , 4 , );
      a.fill( '16px' , 8 , );
      // add more ranges as necessary
      return a;
    }
    
    const computeFontSize = stringLength => {
      const table = fontSizeLookupTable();
      return stringLength < table.length ? table[stringLength] : '16px';
    }
    

    通过经验测试调整和调整所有参数。

    【讨论】:

    • 参数的实证检验本质上是一个时间复杂度为 O(log n) 的二分查找。
    • 你居然忘了调用这个函数,数组长度也需要用它的属性来访问。
    • @lukk:感谢您的反馈。现在修好了。
    【解决方案8】:
    calc(42px + (60 - 42) * (100vw - 768px) / (1440 - 768));
    

    使用这个等式。

    对于任何大于或小于 1440 和 768 的值,您可以给它一个静态值,或应用相同的方法。

    vw 解决方案的缺点是您无法设置缩放比例,例如屏幕分辨率为 1440 的 5vw 最终可能是 60px 字体大小,您的想法字体大小,但是当您将窗口宽度缩小到 768 时,它最终可能是 12px,而不是你想要的最小值。使用这种方法,您可以设置上边界和下边界,字体会在两者之间自行缩放。

    【讨论】:

      【解决方案9】:

      试试 MartijnCuppens 的 RFS (for responsive font size) 库,它可能是 implemented in Bootstrap

      【讨论】:

      • 现在在 Bootstrap 5 中默认启用。
      【解决方案10】:

      这个解决方案也可能有帮助:

      $(document).ready(function () {
          $(window).resize(function() {
              if ($(window).width() < 600) {
                  $('body').css('font-size', '2.8vw' );
              } else if ($(window).width() >= 600 && $(window).width() < 750) {
                  $('body').css('font-size', '2.4vw');
              } 
               // and so on... (according to our needs)
              } else if ($(window).width() >= 1200) {
                  $('body').css('font-size', '1.2vw');
              }
          }); 
        });
      

      它对我很有效!

      【讨论】:

      • 这是如何考虑自动换行的?
      【解决方案11】:

      您可能对calc 方法感兴趣:

      font-size: calc(4vw + 4vh + 2vmin);
      

      完成。调整值直到符合您的口味。

      来源:https://codepen.io/CrocoDillon/pen/fBJxu

      【讨论】:

        【解决方案12】:

        正如 cmets 中 @DMTinter 的帖子中提到的许多人所提到的,OP 询问的是字符数量(“数量”)的变化。他也在询问 CSS,但正如@Alexander 指出的那样,“仅使用 CSS 是不可能的”。据我所知,目前这似乎是正确的,因此人们想知道下一个最好的事情似乎也是合乎逻辑的。

        我对此并不特别自豪,但它确实有效。似乎需要大量的代码来完成它。这是核心:

        function fitText(el){
          var text = el.text();
          var fsize = parseInt(el.css('font-size'));
          var measured = measureText(text, fsize);
        
          if (measured.width > el.width()){
            console.log('reducing');
            while(true){
              fsize = parseInt(el.css('font-size'));
              var m = measureText(text, fsize );
              if(m.width > el.width()){
                el.css('font-size', --fsize + 'px');
              }
              else{
                break;
              }
            }
          }
          else if (measured.width < el.width()){
            console.log('increasing');
            while(true){
              fsize = parseInt(el.css('font-size'));
              var m = measureText(text, fsize);
              if(m.width < el.width()-4){ // not sure why -4 is needed (often)
                el.css('font-size', ++fsize + 'px');
              }
              else{
                break;
              }
            }
          }
        }
        

        这是一个 JS Bin:http://jsbin.com/pidavon/edit?html,css,js,console,output
        请提出可能的改进建议(我对使用画布测量文本并不感兴趣......似乎开销太大(?))。

        感谢@Pete 提供 measureText 功能: https://stackoverflow.com/a/4032497/442665

        【讨论】:

          【解决方案13】:

          唯一的方法可能是为不同的屏幕尺寸设置不同的宽度,但这种方法非常不准确,你应该使用 js 解决方案。

          h1 {
              font-size: 20px;
          }
          
          @media all and (max-device-width: 720px){
              h1 {
                  font-size: 18px;
              }
          }
          
          @media all and (max-device-width: 640px){
              h1 {
                  font-size: 16px;
              }
          }
          
          @media all and (max-device-width: 320px){
              h1 {
                  font-size: 12px;
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2014-09-04
            • 2016-09-24
            • 1970-01-01
            • 2015-09-09
            • 2016-09-17
            • 2014-03-17
            • 1970-01-01
            • 1970-01-01
            • 2014-11-02
            相关资源
            最近更新 更多