我很难理解字体缩放。

我目前有一个字体大小为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;
    }
}

其他回答

我自己的解决方案,基于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;
};

SVG解决方案:

.树脂土{调整大小:两者;边距:0;填充:0;高度:75px;宽度:500px;背景色:浅蓝色;溢出:隐藏;}<div class=“resizeme”><svg宽度=“100%”高度=“100%”viewBox=“0 0 500 75”preserveAspectRatio=“xMinYMid满足”style=“背景色:绿色”xmlns=“http://www.w3.org/2000/svg"xmlns:xlink=“http://www.w3.org/1999/xlink"><文本x=“0”y=“75”font size=“75”fill=“黑色”>█调整此大小█</文本></svg></div>

使用foreignObject的SVG和文本换行解决方案:

.树脂土{调整大小:两者;边距:0;填充:0;高度:200px;宽度:500px;背景色:浅蓝色;溢出:隐藏;}<div class=“resizeme”><svg宽度=“100%”高度=“100%”viewBox=“0 0 500 200”preserveAspectRatio=“xMinYMin满足”><foreignObject width=“100%”height=“100%”xmlns=“http://www.w3.org/1999/xhtml"><div xmlns=“http://www.w3.org/1999/xhtml“style=”背景色:浅绿色;"><h1>标题</h1><p>调整蓝色框的大小</p></div></foreignObject></svg></div>

我准备了一个简单的缩放函数,使用CSS转换而不是字体大小。您可以在任何容器中使用它,不必设置媒体查询等:)

博客文章:全宽CSS和JS可扩展标头

代码:

function scaleHeader() {
  var scalable = document.querySelectorAll('.scale--js');
  var margin = 10;
  for (var i = 0; i < scalable.length; i++) {
    var scalableContainer = scalable[i].parentNode;
    scalable[i].style.transform = 'scale(1)';
    var scalableContainerWidth = scalableContainer.offsetWidth - margin;
    var scalableWidth = scalable[i].offsetWidth;
    scalable[i].style.transform = 'scale(' + scalableContainerWidth / scalableWidth + ')';
    scalableContainer.style.height = scalable[i].getBoundingClientRect().height + 'px';
  }
}

工作演示:https://codepen.io/maciejkorsan/pen/BWLryj

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

理论:

传入需要匹配的字符串传入要从中继承文本样式的父级可选地传入自定义属性(例如,您将从中继承字体和其他属性的类/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;`;  

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