视窗单位的趣味

Avatar of Miriam Suzanne
Miriam Suzanne 发布

DigitalOcean 提供适用于您旅程各个阶段的云产品。立即开始使用 价值 200 美元的免费积分!

视窗单位已经存在好几年了,并且在主要浏览器中 几乎获得了完美支持,但我仍然不断地发现新的和令人兴奋的使用方法。我认为回顾基础知识,然后总结一些我最喜欢的用例会很有趣。

视窗单位是什么?

在 2011 年到 2015 年之间,CSS 规范中出现了四个新的“视窗相对”单位,作为 W3C 的 CSS 值和单位模块级别 3 的一部分。这些新单位——vwvhvminvmax——与现有的长度单位(如 pxem)的工作原理类似,但代表当前浏览器视窗的百分比。

  • 视窗宽度 (vw) – 视窗全宽的百分比。10vw 将解析为当前视窗宽度的 10%,或者在 480px 宽的手机上解析为 48px%vw 之间的区别最类似于 emrem 之间的区别。% 长度相对于本地上下文(包含元素)宽度,而 vw 长度相对于浏览器窗口的总宽度。
  • 视窗高度 (vh) – 视窗全高的百分比。10vh 将解析为当前视窗高度的 10%
  • 视窗最小值 (vmin) – 视窗宽度或高度的百分比,取较小者10vmin 将在纵向方向上解析为当前视窗宽度的 10%,而在横向方向上解析为视窗高度的 10%
  • 视窗最大值 (vmax) – 视窗宽度或高度的百分比,取较大者10vmax 将在纵向方向上解析为当前视窗高度的 10%,而在横向方向上解析为视窗宽度的 10%。遗憾的是,奇怪的是,vmax 单位目前在 Internet Explorer 或 Edge 上不可用。

虽然这些单位源自视窗高度或宽度,但它们都可以在接受长度的所有地方使用——从 font-size 到定位、边距、填充、阴影、边框等等。让我们看看我们能做些什么!

响应式排版

使用视窗单位进行响应式排版变得非常流行——建立根据当前视窗大小而增长和缩小的字体大小。使用简单的视窗单位进行字体大小设置有一个有趣(危险)的效果。正如您所看到的,字体缩放非常快——在一个很小的范围内从不可读的小字体调整到超大字体。

这种直接缩放显然对于日常使用来说过于剧烈。我们需要更细微的东西,带有最小值和最大值,以及对增长率的更多控制。这就是 calc() 变得有用的地方。我们可以将一个基本大小用更稳定的单位(比如 16px)与一个更小的视窗相对调整(0.5vw)结合起来,让浏览器进行计算:calc(16px + 0.5vw)

通过更改基本大小和视窗相对调整之间的关系,您可以更改增长率的剧烈程度。在标题上使用更高的视窗值,并观察它们比周围文字更快地增长。这允许在更大的屏幕上获得更动态的排版比例,同时在移动设备上保持字体约束——无需媒体查询。您还可以 将此技术应用于您的行高,让您可以以与 font-size 不同的速率调整行高。

body {
  // font grows 1px for every 100px of viewport width
  font-size: calc(16px + 1vw);
  // leading grows along with font,
  // with an additional 0.1em + 0.5px per 100px of the viewport
  line-height: calc(1.1em + 0.5vw);
}

对我来说,这已经足够复杂了。如果我需要为快速增长的标题约束顶端,我可以使用一个单独的媒体查询,无论何时文本变得太大。

h1 {
  font-size: calc(1.2em + 3vw);
}

@media (min-width: 50em) {
  h1 {
    font-size: 50px;
  }
}

突然间,我真希望有一个 max-font-size 属性。

其他人已经开发了更复杂的计算和 Sass 混合宏来指定特定媒体查询处的精确文字大小范围。现有的几篇 CSS-Tricks 文章解释了这种技术并提供了代码段,帮助您入门

我认为在大多数情况下这有点过分了,但您的实际情况肯定会有所不同。

全高布局、英雄图片和固定页脚

全高(或高度受限)布局有很多变体——从桌面风格的界面到英雄图片、宽敞的设计和 固定页脚。视窗单位可以帮助解决所有这些问题。

桌面风格的全高界面中,页面通常被分成单独滚动的部分——带有像标题、页脚和侧边栏这样的元素,这些元素在任何大小下都保持在适当的位置。这在如今的许多网络应用程序中很常见,而 vh 单位使它变得更加简单。以下是一个使用新的 CSS Grid 语法的示例

查看 CodePen 上 Miriam Suzanne (@mirisuzanne) 的 全高 CSS Grid 笔记。

body 元素上的单个声明 height: 100vh 将您的应用程序限制在视窗的高度内。确保在内部元素上应用 overflow 值,这样您的内容就不会被切断。您还可以使用 Flexbox浮动 来实现这种布局。请注意,全高布局可能会在一些移动浏览器上造成问题。有一个 针对 iOs Safari 的巧妙解决方案,我们使用它来处理最明显的边缘情况之一。

固定页脚可以用类似的技术创建。将您的 body 元素的 height: 100vh 更改为 min-height: 100vh,页脚将保持在屏幕底部,直到被内容推下。

查看 CodePen 上 Miriam Suzanne (@mirisuzanne) 的 使用 CSS Grid 的固定页脚 笔记。

vh 单位应用于不同元素的 heightmin-heightmax-height,以创建全屏部分英雄图片等等。在新的 OddBird 重构 中,我们用 max-height: 55vh 限制了我们的英雄图片,这样它们就不会将标题推离页面。在我的个人网站上,我使用了 max-height: 85vh 来营造更多以图片为主导的外观。在其他网站上,我将 min-height: 90vh 应用于部分。

以下是一个展示了 最大高度的英雄猫咪和最小高度的部分 的示例。结合所有这些技巧,可以让您对内容如何填充浏览器窗口以及如何 响应不同的视窗 有强大的控制。

流体纵横比

约束元素的高度与宽度之比也很有用。这对于嵌入内容(如视频)特别有用。 Chris 之前写过这方面的内容。在过去,我们会使用容器元素上的 % 基填充和内部元素上的绝对定位来实现这一点。现在,我们有时可以使用视窗单位来实现这种效果,而无需额外的标记。

如果我们可以依靠视频全屏显示,我们可以将高度设置为相对于视窗全宽

/* full-width * aspect-ratio */
.full-width {
  width: 100vw;
  height: calc(100vw * (9/16));
}

这种数学运算不需要在浏览器中使用 calc 完成。如果您使用的是像 Sass 这样的预处理器,它在预处理器中完成数学运算的效果一样好:height: 100vw * (9/16)。如果您需要约束最大宽度,您也可以约束最大高度

/* max-width * aspect-ratio */
.full-width {
  width: 100vw;
  max-width: 30em;
  height: calc(100vw * (9/16));
  max-height: calc(30em * (9/16));
}

以下是一个演示了两种选项的示例,使用 CSS 自定义属性(变量)来使数学运算更具语义性。随意修改数字以查看事物如何移动,始终保持正确的比例

查看 CodePen 上 Miriam Suzanne (@mirisuzanne) 的 使用视窗单位的流体比例 笔记。

Chris 在他的预视窗单位文章中更进一步,我们也一样。如果我们需要实际的 HTML 内容在设定比例内缩放,就像演示文稿幻灯片通常所做的那样,该怎么办?

我们可以使用与容器相同的视窗单位来设置我们所有内部字体和大小。在这种情况下,我使用 vmin 来设置所有内容,这样内容会随着容器高度和宽度的变化而缩放

查看 CodePen 上 Miriam Suzanne (@mirisuzanne) 的 使用视窗单位的流体幻灯片比例 笔记。

打破容器

多年来,将受限文字与全宽背景混合在一起一直很流行。根据您的标记或 CMS,这可能会变得很困难。如何将内容从受限容器中分离出来,使其完全填充视窗?

同样,视窗单位可以派上用场。这是我们在新的 OddBird 网站上使用的另一个技巧,在该网站上,静态网站生成器有时会限制我们对标记的控制。只需要几行代码就能让它起作用。

.full-width {
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
}

Cloud Four 和 CSS-Tricks 上都有关于这种技术的更深入的文章。 CSS Tricks.

越来越奇怪

当然,如果您开始尝试,还可以使用视窗单位做更多的事情。看看这个纯 CSS 滚动指示器(由一位名叫 Mike 的人制作),它在背景图片上使用视窗单位。

查看代码笔 CSS only scroll indicator by Mike (@MadeByMike) on CodePen.

您还使用视窗单位看到了或做了什么?发挥创意,向我们展示结果!