我很难理解字体缩放。

我目前有一个字体大小为100%的网站。但这是100%的吗?这似乎是在16个像素处计算出来的。

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

如何使站点上的文本与其容器相关?我尝试过使用它们,但这也无法扩展。

我的理由是,当你调整大小时,像我的菜单这样的东西会变得压扁,所以我需要减少.menuItem等元素相对于容器宽度的px字体大小。(例如,在大型桌面上的菜单中,22px的效果非常好。向下移动到平板电脑宽度,16px更合适。)

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


当前回答

直接媒体查询似乎是一种更简单、更容易理解的解决方案,可以根据容器大小调整字体大小,而容器大小可能是动态的。

下面将根据容器的大小调整字体大小,无论容器是否缩放到视口的大小,或是否已达到其最大值。如果您有非100%宽的容器,可以相应地调整vw。

.container {
    width: 100%;
    max-width: 600px;
}
.headline {
    font-size: 20vw;
}
.subhead {
    font-size: 5vw;
}
@media (min-width:600px) {
    .headline {
        font-size: 120px;
    }
    .subhead {
        font-size: 32px;
    }
}

其他回答

始终使元素具有此属性:

JavaScript:element.style.fontSize=“100%”;

or

CSS:style=“font-size:100%;”

当您进入全屏时,您应该已经计算了一个比例变量(比例>1或比例=1)。然后,在全屏幕上:

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

它只需要很少的代码就可以很好地工作。

我想喜欢接受的答案,但从根本上说,符合我的标准的答案都需要使用图书馆。我决定编写一个非常适合我的简单函数,而不是让自己熟悉另一个库,然后找出如何使用它并准备在它不工作时进行调试。

理论:

传入需要匹配的字符串传入要从中继承文本样式的父级可选地传入自定义属性(例如,您将从中继承字体和其他属性的类/id,或者仅传入自定义内联样式)函数将在屏幕外创建一个文本元素,其中包含该文本、该父元素和这些属性,字体大小为1px,并对其进行测量然后,在循环中,它将逐像素增加字体大小,直到超过宽度限制;一旦完成,它将返回最后一个合适的然后删除测试元素当然,这一切都发生在眨眼之间

限制:

我不在乎动态调整屏幕大小,因为这与我的上下文无关。在生成文本时,我只关心运行时的屏幕大小。我依赖一个小助手函数,我也在代码的其他地方使用它,它基本上作为mithril.js的单函数版本存在;老实说,我几乎在每个项目中都使用这个小功能,它值得自己学习。

  function findMaxFontSize(
    string="a string", 
    parent=document.body, 
    attributes={id:'font-size-finder',class:'some-class-with-font'}
  ) {
    // by using parent, we can infer the same font inheritance;
    // you can also manually specify fonts or relevant classes/id with attributes if preferred/needed
    attributes.style = 'position:absolute; left:-10000; font-size:1px;' + (attributes.style || "");
    let testFontEl = createEl('p', attributes, string);
    parent.appendChild(testFontEl);
    let currentWidth = testFontEl.offsetWidth;
    let workingFontSize = 1;
    let i = 0;
    while (currentWidth < maxWidth && i < 1000) {
      testFontEl.style.fontSize = Number(testFontEl.style.fontSize.split("px")[0]) + 1 + "px";
      currentWidth = testFontEl.offsetWidth;
      if (currentWidth < maxWidth) {
        workingFontSize = testFontEl.style.fontSize;
      }
      i++; // safety to prevent infinite loops
    }
    console.log("determined maximum font size:",workingFontSize,'one larger would produce',currentWidth,'max width allowed is',maxWidth,'parent is',parent);
    parent.removeChild(testFontEl);
    return workingFontSize.split("px")[0];
  }
// utility function, though you could easily modify the function above to work without this.
  // normally these have no default values specified, but adding them here
  // to make usage clearer.
  function createEl(tag="div", attrs={class:'some-class'}, children=[]) {
    let el = document.createElement(tag);
    if (attrs) {
      Object.keys(attrs).forEach(attr => {
        el.setAttribute(attr, attrs[attr])
      })
    }
    if (children) {
      children = Array.isArray(children) ? children : [children];
      for (let child of children) {
        if (typeof child === "number") child = ""+child;
        if (typeof child === "string") {
          el.insertAdjacentText("afterbegin", child);
        }
        else {
          try {
            el.appendChild(child)
          } catch (e) {
            debugger
          }
        }
      }
    }
    return el;
  };

use:

    const getUsername = () => "MrHarry";
    const username = getUsername();
    const anchor = document.querySelector('.container');
    const titleFontSize = findMaxFontSize(`Welcome, ${username}`, anchor, {style:'font-weight:900;'});
    const titleFontStyle = `font-size:${titleFontSize}px;`;  

此web组件更改字体大小,使内部文本宽度与容器宽度匹配。查看演示。

您可以这样使用:

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

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

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

这对我有用:

我尝试根据设置“字体大小:10px”得到的宽度/高度来近似字体大小。基本上,这个想法是“如果我有20像素宽和11像素高的‘字体大小: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元素或小于其父元素的元素,否则如果子元素和父元素都具有相同的宽度/高度,则函数将失败。