视窗大小的排版

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 $200 免费积分!

CSS 中有一些值用于根据视窗(浏览器窗口的大小)来调整大小。它们被称为 **视窗单位**,有很多这样的单位,它们做的事情略有不同(都是有用的)。一个单位是视窗轴的 1%。这些单位对于响应式设计很有用,也就是说,设计在不同屏幕尺寸下都能很好地显示的网站,利用可用的空间。

您可以使用视窗单位做很多事情,但让我们看看其中一项: **排版**。

值得一看我们最近的文章 简化流体排版,它介绍了实用的、夹紧的、基于视窗的类型大小调整。

为什么这很棒?

有很多原因。这里列举两个

  1. 屏幕上阅读文本有一个舒适的线长。我不想惹麻烦,但让我们说大约是 80 个字符。这些单位允许您将它调整到完美的感觉,然后让这种体验扩展到任何尺寸的屏幕。
  2. 它们允许您将排版标题和它所包含的内容的大小关系紧密地耦合在一起。就像你的 经典 Trent Walton 风格的博客文章

它们是如何工作的

这三个值中的一个单位是视窗轴的 1%。 “视窗” == 浏览器窗口大小 == 窗口对象。如果视窗宽度为 40 厘米,则 1vw == 0.4 厘米。

用于 font-size 时,我想它是一个具有该大小的“字母”,但正如我们所知,在非等宽字体中,字母的宽度是相当任意的。我发现你只需要调整一下值就可以得到你想要的效果。这基本上就是我们一直在做的事情,对吧?

  • 1vw = 视窗宽度的 1%
  • 1vh = 视窗高度的 1%
  • 1vmin = 1vw1vh 中较小的一个
  • 1vmax = 1vw1vh 中较大的一个

使用它们

简单易用

h1 {
  font-size: 5.9vw;
}
h2 {
  font-size: 3.0vh;
}
p {
  font-size: 2vmin;
}

演示

这是一个使用 vw 单位作为 font-size简单布局 的视频。

自己查看 演示(查看浏览器支持)。

或者这里有一个超简单的标题的 GIF

错误!

Chrome 20+ / Safari 6+ 中有支持,但它在一种相当重要的方式上失败了。当浏览器窗口大小调整时,字体不会根据新的视窗大小进行调整。规范说

当视窗的高度或宽度发生变化时,它们将相应地缩放。

提交了错误报告。可能这不是一个很大的灾难,因为只有我们这些设计狂热分子才会不断调整浏览器窗口,但它仍然存在。字体在页面重新加载时会进行调整。

要解决这个问题(允许在不刷新页面情况下调整大小),您需要对元素进行“重绘”。我使用了 jQuery 并且只是调整了每个元素(在这种情况下无关紧要)的 z-index 值,这会触发重绘。

causeRepaintsOn = $("h1, h2, h3, p");

$(window).resize(function() {
  causeRepaintsOn.css("z-index", 1);
});

更新:不必担心这个问题了,也绝对不要强制重绘。Chrome 34+ 和 Safari 7+ 中已经修复了此调整大小问题。在移动设备上更改视窗大小并不常见,所以我不知道这个错误是否曾经影响到它们。

浏览器支持

IE 10+,Firefox 19+,Chrome 34+,Safari 7+,Android 4.4+,iOS 6+支持

Chrome 20-34,Safari 6支持,但存在重绘问题

它们还存在一些其他特定的跨浏览器怪异问题,在 Can I Use 上有记录

不仅仅是 font-size

记录一下,这些只是一些单位。就像 empx 等等。您可以将它们用于任何东西,而不仅仅是 font-size

我认为 font-size 是最引人注目的用例,因为像 margin、padding 和 width 这样的东西已经可以基本上通过使用 % 单位来响应浏览器窗口大小。在这种情况下,可能需要一个更深层的嵌套元素来响应浏览器窗口大小而不是它的直接父元素大小。

现在使用它

原生用法

您至少需要提供一个回退

h1 {
  font-size: 36px; /* Some tweener fallback that doesn't look awful */ 
  font-size: 5.4vw;  
}

测试支持

Modernizr 还没有 测试,但您可以自己测试。方法是使用一些一次性元素,在 CSS 中将其设置成很窄的宽度,然后在 JavaScript 中将其重新设置为 100vw,然后测量其宽度是否等于 window.width。类似于

var testEl = $("#vw-test");

testEl.css({
  width: "100vw"
});

if (testEl.width() == window.innerWidth) {
   // Supported
} else {
   // Not Supported
};

这是 在 CodePen 上的测试,但请注意它只在全页视图中有效,否则由于 iframe 问题,计算结果可能不准确。

使用 FitText.js 模仿功能

将标题的总宽度与其父元素的宽度绑定在一起的想法正是 FitText.js 所做的。只是它通过精妙的 JavaScript、数学运算、跨度等等来实现。理论上,您可以运行测试,并使用 Modernizr.load 在检测到不支持的情况下加载 FitText.js。

更多信息