纯CSS可根据动态字符数量使字体大小响应

问题描述 投票:260回答:10

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

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

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

我想也许这可以通过在ems中指定容器的宽度,并使字体大小继承该值来实现?

css css3
10个回答
463
投票

我刚刚发现这可以使用大众单位。它们是与设置视口宽度相关联的单位。有一些缺点,例如缺乏传统的浏览器支持,但这绝对值得认真考虑使用。另外,您仍然可以为旧浏览器提供后备服务,例如:

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

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


2
投票
calc(42px + (60 - 42) * (100vw - 768px) / (1440 - 768));

使用这个等式。

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

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


102
投票

CSS3支持相对于视口的新维度。但这在android <4.4中不起作用

  1. 3.2vw =视口宽度的3.2%
  2. 3.2vh =视口高度的3.2%
  3. 3.2vmin = 3.2vw或3.2vh的较小值
  4. 3.2vmax = 3.2vw或3.2vh的较大值 body { font-size: 3.2vw; }

看看css-tricks.com/....,还看看caniuse.com/....

要么

使用媒体查询。最简单的方法是使用%或em中的维度。只需更改基本字体大小,一切都会改变。

@media (max-width: @screen-xs) {
    body{font-size: 10px;}
}

@media (max-width: @screen-sm) {
    body{font-size: 14px;}
}


h5{
    font-size: 1.4em;
}

使用%或em中的维度。只需更改基本字体大小,一切都会改变。在上一个中,您可以只更改正文字体而不是每次更改h1,或者让基本字体大小为设备的默认值,并将其全部放在em中

有关em,px和%的更多信息,请参阅kyleschaeffer.com/....


19
投票

您可能对calc方法感兴趣:

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

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

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


11
投票

唯一的方法可能是为不同的屏幕尺寸设置不同的宽度,但这种方法非常简单,你应该使用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;
    }
}

11
投票

我知道我正在重新解决一个长期存在的问题,但我有同样的问题,我想补充一些东西。请不要因为这个而禁止我,我觉得重要的是要证明这个答案,如果需要,我会删除。 @Joseph Silber错了,编码所有可能性实际上是一种可行的方法来做到这一点。原因是因为实际上没有无限的可能性。嗯,技术上有,但99%的访问者将使用标准分辨率。这对于移动设备来说是双重的(响应式网页设计的主要原因),因为大多数移动操作系统全屏运行应用程序,没有窗口大小调整。

此外,由于滚动条的高度几乎无关紧要(到一定程度,我会立即留下一个超过4或5英尺长的网页,但这大部分都是正确的),所以你只需要担心宽度。实际上,您需要编码的唯一宽度如下:240,320,480(对于较旧的iThings),640,800,1024,1280,1440,1600,1920,2048,2560。甚至不打扰4k,它会使你的图像膨胀太多,2560尺寸拉伸到100%宽度在4k显示器上看起来很好(我已经测试了这个)。另外,不要像上一张海报建议的那样打扰720(720x480)。它的分辨率几乎完全由数码相机使用,即便如此,它也非常罕见。

如果有人使用异国情调的分辨率,那么过去15年中制作的几乎所有渲染器都会向下舍入,所以如果有人的屏幕宽度是,那么。 1100,它将加载1024 CSS规则,您的网站不应该破坏。这通过尝试创建不必要的响应规则来呈现异常分辨率,并且您需要逐个像素地为每个可能的设置进行编码的想法是荒谬的,除非有人使用网络浏览器如此过时以至于您的网站可能无法加载无论如何。


4
投票

作为参考,这是一个JS解决方案,根据容器内的文本长度重新调整字体大小。

Codepen略有修改代码,但同样的想法如下:

function scaleFontSize(element) {
    var container = document.getElementById(element);

    // We only want to scale down long text, so first we reset
    // font-size to 100%, in case this function is called multiple times.
    container.style.fontSize = "100%";

    // Now actually 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;
}

所以,最终:

  • 短文:例如“苹果” 完全渲染,漂亮的大字母。
  • 长文:例如“APPLES&ORANGES” 通过上面的JS缩放功能,缩小70%。
  • 超长文本:例如“APPLES&ORANGES&BANAN ......” 通过上面的JS缩放函数和CSS规则,缩小70%并使用“...”省略号截断。

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


2
投票

正如许多人在评论@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 请建议对它进行可能的改进(我对使用canvas来测量文本并不感兴趣......看起来似乎太多开销(?))。

感谢@Pete for measureText函数:https://stackoverflow.com/a/4032497/442665


2
投票

此解决方案也可能有所帮助

$(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');
        }
    }); 
  });

它对我有用!


2
投票

试试MartijnCuppens的RFS (for responsive font size)库,也许是implemented in Bootstrap

© www.soinside.com 2019 - 2024. All rights reserved.