基于容器宽度的字体缩放

CSS

伽罗Itachi

2020-03-13

我很难理解字体缩放。

目前,我有这个网站与身体font-size的100%。不过是100%这似乎可以计算出16个像素。

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

如何使网站上的文字相对于其容器而言?我尝试使用em,但这也无法扩展。

我的理由是,当你调整,这东西像我的菜单中就被压扁,所以我需要降低px font-size.menuItem相对其它元素的容器的宽度之中。(例如,在大型桌面上的菜单中,22px效果很好。向下移动至数位板宽度16px比较合适。)

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

第1561篇《基于容器宽度的字体缩放》来自Winter(https://github.com/aiyld/aiyld.github.io)的站点

15个回答
泡芙小胖 2020.03.13

从艺术上讲,如果您需要在同一宽度内容纳两行或更多行文本,而不管它们的字符数如何,那么您就有不错的选择。

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

让我们看看我们该如何处理。

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")))作为参考,然后相应地计算后续行的字体大小。

猿蛋蛋凯 2020.03.13

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

Near神乐路易 2020.03.13

这为我工作:

我尝试根据设置`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元素或一个小于其父元素的元素,否则,如果子元素和parent都具有相同的width / height函数,则该函数将失败。

猪猪前端 2020.03.13

始终使您的元素具有以下属性:

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

要么

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

全屏显示时,您应该已经计算出一个比例变量(比例> 1或比例= 1)。然后,在全屏模式下:

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

只需少量代码即可很好地工作。

西门JinJin 2020.03.13

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

达蒙小哥 2020.03.13

尝试http://simplefocus.com/flowtype/这就是我在网站上使用的,并且效果很好。

村村蛋蛋 2020.03.13

Take look at my code. It makes the font size smaller to fit whatever there.

但是我认为这并不能带来良好的用户体验

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

结果

Mandy猴子 2020.03.13

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

    @media only screen and (max-width: 320px) {

        body { font-size: 1em; }

    }

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

猪猪阳光 2020.03.13

100%相对于基本字体大小,如果未设置,则为浏览器的用户代理默认值。

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

老丝Stafan 2020.03.13

该Web组件更改字体大小,以便内部文本宽度与容器宽度匹配。检查演示

您可以像这样使用它:

<full-width-text>Lorem Ipsum</full-width-text>
Eva西里蛋蛋 2020.03.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;
};
→笑里藏刀↓ 2020.03.13

这是函数:

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

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

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

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

http://jsfiddle.net/0tpvccjt/

null 2020.03.13

没有 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/

米亚阿飞 2020.03.13

SVG解决方案:

<div style="width: 60px;">  
  <svg width="100%" height="100%" viewBox="0 -200 1000 300"
     xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <text font-size="300" fill="black">Text</text>
  </svg>
</div>

https://jsfiddle.net/qc8ht5eb/


使用SVG和文本包装的解决方案foreignObject

<svg viewBox="0 0 100 100">
  <foreignObject width="100%" height="100%">
    <h1>heading</h1>

    lorem ipsum dolor sit amet
  </foreignObject>
</svg> 

https://jsfiddle.net/2rp1q0sy/

A村村 2020.03.13

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

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

我知道这不能回答OP的问题,但是也许可以解决其他任何问题。

问题类别

JavaScript Ckeditor Python Webpack TypeScript Vue.js React.js ExpressJS KoaJS CSS Node.js HTML Django 单元测试 PHP Asp.net jQuery Bootstrap IOS Android