纯 CSS 使字体大小响应基于动态字符量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14431411/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 21:23:36  来源:igfitidea点击:

Pure CSS to make font-size responsive based on dynamic amount of characters

css

提问by DMTintner

I know that this could be solved fairly easily with Javascript, but I'm only interested in a pure CSS solution.

我知道使用 Javascript 可以很容易地解决这个问题,但我只对纯 CSS 解决方案感兴趣。

I want a way to dynamically resize text so that it always fits into a fixed div. Here is the sample markup:

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

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

I was thinking that maybe this could be possible by specifying the width of the container in ems, and getting the font-size to inherit that value?

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

回答by DMTintner

I just found out that this is possible using VW units. They're the units associated with setting the viewport width. There are some drawbacks, such as lack of legacy browser support, but this is definitely something to seriously consider using. Plus you can still provide fallbacks for older browsers like so:

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

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

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

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

回答by aWebDeveloper

CSS3supports new dimensions that are relative to view port. But this doesn't work in android < 4.4

CSS3支持与视口相关的新尺寸。但这在 android < 4.4 中不起作用

  1. 3.2vw = 3.2% of width of viewport
  2. 3.2vh = 3.2% of height of viewport
  3. 3.2vmin = Smaller of 3.2vw or 3.2vh
  4. 3.2vmax = Bigger of 3.2vw or 3.2vh

    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 中的较大者

    body
    {
        font-size: 3.2vw;
    }
    

see css-tricks.com/....and also look at caniuse.com/....

参见css-tricks.com/....并查看caniuse.com/....

or

或者

Use media query.Simplest way is to use dimensions in % or em. Just change the base font size everything will change.

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

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

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


h5{
    font-size: 1.4em;
}

Use dimensions in % or em. Just change the base font size everything will change. In previous one you could just change the body font and not h1 every time or let base font size to default of the device and rest all in em

使用% 或 em 中的尺寸。只需更改基本字体大小,一切都会改变。在前一个中,您可以每次更改正文字体而不是 h1 或让基本字体大小为设备的默认值并全部保留在 em

see kyleschaeffer.com/....for more info on em, px and %

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

回答by KhoPhi

You might be interested in the calcapproach:

您可能对这种calc方法感兴趣:

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

done. Tweak values till matches your taste.

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

Source: https://codepen.io/CrocoDillon/pen/fBJxu

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

回答by Sven Rojek

The only way would probably be to set different widths for different screen sizes, but this approach is pretty inacurate and you should use a js solution.

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

回答by user281058

I know I'm ressurecting a long dead question, but I had the same question and I wanted to add something. Please don't ban me for this, I felt it was important enough to justify this answer, I'll delete if required. @Joseph Silber is wrong, coding all the possibilities actually is a viable way to do this. The reason is because there actually aren't infinite possibilities. Well, technically there are, but 99% of your visitors will be using a standard resolution. This is doubly true for mobile (the main reason for responsive web design) because most mobile OSes run apps full screen with no window resizing.

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

Also, height is pretty much irrelevant because of the scrollbar (to a point, I would immediately leave a web page that was more than 4 or 5 feet long, but this mostly holds true), so you only need to worry about width. And really, the only widths you need to code for are the following: 240, 320, 480 (for older iThings), 640, 800, 1024, 1280, 1440, 1600, 1920, 2048, 2560. Don't even bother for 4k, it will bloat your images too much and the 2560 size stretched to 100% width looks just fine on a 4k monitor (I've tested this). Also, don't bother with 720 (720x480) as the previous poster suggested. Its a resolution used almost exclusively by digital cameras, and even then its very uncommon.

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

If someone is using an exotic resolution, nearly any renderer made in the past 15 years will round down, so if someone's screen width is, say. 1100, its going to load the 1024 CSS rule, your site shouldn't break. This renders accounting for exotic resolutions by trying to create a responsive rule unnecessary, and the idea that you need to code for every possible setup pixel by pixel is ridiculous, unless someone's using a web browser so outdated that your site probably wouldn't load at all anyway.

如果有人使用奇异的分辨率,那么过去 15 年中制作的几乎所有渲染器都会四舍五入,所以如果有人的屏幕宽度是,那么。1100,它将加载 1024 CSS 规则,您的站点不应中断。这使得通过尝试创建一个不必要的响应规则来考虑奇异的分辨率,并且您需要为每个可能的设置逐像素编码的想法是荒谬的,除非有人使用过时的网络浏览器以至于您的网站可能无法加载无论如何。

回答by MarsAndBack

For reference, a non-CSS solution:

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

Below is some JS that re-sizes a font depending on the text length within a container.

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

Codepenwith slightly modified code, but same idea as below:

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%";
    }
}

For me, I call this function when a user makes a selection in a drop-down, and then a div in my menu gets populated (this is where I have dynamic text occurring).

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

    scaleFontSize("my_container_div");

In addition, I also use CSS ellipses ("...") to truncate yet even longertext too, like so:

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

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

So, ultimately:

所以,最终:

  • Short text:e.g. "APPLES"

    Fully rendered, nice big letters.

  • Long text:e.g. "APPLES & ORANGES"

    Gets scaled down 70%, via the above JS scaling function.

  • Super long text:e.g. "APPLES & ORANGES & BANAN..."

    Gets scaled down 70% AND gets truncated with a "..." ellipses, via the above JS scaling function together with the CSS rule.

  • 短文本:例如“苹果”

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

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

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

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

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

You could also explore playing with CSS letter-spacing to make text narrower while keeping the same font size.

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

回答by Fred K

Try RFS (for responsive font size)library by MartijnCuppens that maybe will be implemented in Bootstrap

试试MartijnCuppens 的RFS(响应字体大小)库,它可能会在 Bootstrap 中实现

回答by Shuwei

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

use this equation.

使用这个等式。

For anything larger or smaller than 1440 and 768, you can either give it a static value, or apply the same approach.

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

The drawback with vw solution is that you cannot set a scale ratio, say a 5vw at screen resolution 1440 may ended up being 60px font-size, your idea font size, but when you shrink the window width down to 768, it may ended up being 12px, not the minimal you want. With this approach, you can set your upper boundary and lower boundary, and the font will scale itself in between.

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

回答by jbobbins

As many mentioned in comments to @DMTinter's post, the OP was asking about the number ("amount") of characters changing. He was also asking about CSS, but as @Alexander indicated, "it is not possible with only CSS". As far as I can tell, that seems to be true at this time, so it also seems logical that people would want to know the next best thing.

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

I'm not particularly proud of this, but it does work. Seems like an excessive amount of code to accomplish it. This is the core:

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

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;
      }
    }
  }
}

Here's a JS Bin: http://jsbin.com/pidavon/edit?html,css,js,console,output
Please suggest possible improvements to it (I'm not really interested in using canvas to measure the text...seems like too much overhead(?)).

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

Thanks to @Pete for measureText function: https://stackoverflow.com/a/4032497/442665

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

回答by Gaurav Krishn

This solution might also help :

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

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

It worked for me well !

它对我很有效!