CSS 中有一些值用于根据视窗(浏览器窗口的大小)来调整大小。它们被称为 **视窗单位**,有很多这样的单位,它们做的事情略有不同(都是有用的)。一个单位是视窗轴的 1%。这些单位对于响应式设计很有用,也就是说,设计在不同屏幕尺寸下都能很好地显示的网站,利用可用的空间。
您可以使用视窗单位做很多事情,但让我们看看其中一项: **排版**。
值得一看我们最近的文章 简化流体排版,它介绍了实用的、夹紧的、基于视窗的类型大小调整。
为什么这很棒?
有很多原因。这里列举两个
- 屏幕上阅读文本有一个舒适的线长。我不想惹麻烦,但让我们说大约是 80 个字符。这些单位允许您将它调整到完美的感觉,然后让这种体验扩展到任何尺寸的屏幕。
- 它们允许您将排版标题和它所包含的内容的大小关系紧密地耦合在一起。就像你的 经典 Trent Walton 风格的博客文章。
它们是如何工作的
这三个值中的一个单位是视窗轴的 1%。 “视窗” == 浏览器窗口大小 == 窗口对象。如果视窗宽度为 40 厘米,则 1vw == 0.4 厘米。
用于 font-size
时,我想它是一个具有该大小的“字母”,但正如我们所知,在非等宽字体中,字母的宽度是相当任意的。我发现你只需要调整一下值就可以得到你想要的效果。这基本上就是我们一直在做的事情,对吧?
1vw
= 视窗宽度的 1%1vh
= 视窗高度的 1%1vmin
=1vw
或1vh
中较小的一个1vmax
=1vw
或1vh
中较大的一个
使用它们
简单易用
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
不仅仅是 记录一下,这些只是一些单位。就像 em
、px
等等。您可以将它们用于任何东西,而不仅仅是 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。
更多信息
- David Storey: 响应式视窗单位
非常棒!这是 Web 排版布局的一大进步。
我几天前做了个类似的东西。
onresize=onload=function(){document.body.style.fontSize=window.innerWidth+”px”}
这个方法有效,但是如何在最小尺寸处停止,因为在更小的屏幕上文字会变得太小。
我也做了一个演示
http://maloweb.com/snippets/responsivestuff.html
这是一个很有意思的想法,但是你不能用媒体查询实现几乎相同的效果吗?
可以,但是看起来会很生硬。使用过渡效果会好一些,但你需要大量的媒体查询,这意味着要处理更多 CSS 代码。
我期待着能够使用这个方法。
这个方法在 Safari 5.2(Beta 3)[版本 5.2(7536.6.1)] 上运行良好。
如果在任何屏幕尺寸下都保持 80 个字符的线长,那么在较小的屏幕上可读性会不会成为问题?
当我在手机上查看这个网站时,每行大约有 40 个字符,这已经很小了,我无法想象如果文字缩放到每行 80 个字符,我能读懂内容。
当然,但我认为它的使用场景是那些介于两者之间的媒体查询,或者当客户坚持使用这种方法时。
否则,你就和设备缩放没有任何区别了。
没错,但我认为他指的是,比如 1800 像素宽的屏幕,你可能会得到 250 个字符每行的文字,这很难阅读。
这是一个多么愚蠢的使用示例——在小屏幕上使用难以阅读的微小字体,或者在大屏幕上使用巨大的字体——请不要将此方法用于除标题以外的任何内容!
顺便说一句,如果用户故意调整屏幕字体,会有什么影响?
VW 和 VH 在 IE9 中也有效,尽管它使用 VM 而不是 VMIN。
太酷了!
想知道如何使用滑块来更改网站上的字体大小。
多么糟糕的解决方法!如果你要使用 jQuery 来实现样式选择,它应该支持更多浏览器。
这个方法很好,但文本可读性不仅仅取决于字符行长。实际的物理行长也很重要。当眼睛不得不走更远的距离回到下一行的开头时,阅读文本会更加困难。我希望看到在调整浏览器宽度时可以在单列和双列布局之间切换的网站。
Patrick 说得对。阅读简便性的最大问题是眼球需要在眼窝中来回旋转多少次才能阅读文本。在大屏幕上,这种方法会很快使阅读变得困难。在小屏幕上(正如有人提到的那样),文本将太小而无法阅读。
这并不是说它没有一个有效的范围,但我认为它并不能使阅读变得更容易。
嗨,
你说得对,我也看到了这个问题……
这是一个很棒的证明,证明我们用 CSS 创建的响应式设计技术现在正在被 CSS 开发社区所采用和改进!
讽刺的是,IE 现在在 CSS3 竞赛中领先……
我迫不及待地想看看人们将如何使用它以及 calc 函数。
有人找到了支持 Chrome(视窗单位和 calc)的 polyfill 吗?
我现在就想用它 lol
喜欢新的 CSS3 规范。
我同意 Julian 的观点,IE10 正在取得重大突破。
太棒了!!
演示在我 Chrome 19 beta 中运行良好。其他人可以确认吗?
使用 20.0.1122.0 canary 版本,它可以平滑地缩放。
em?
为什么不使用 em 来设置字体大小(以及其他一切)?
只需要调整基准字体大小,你就可以得到基本相同的结果。目前 JavaScript 可以用几行代码完成这项工作,calc() 可以在不久的将来实现这种功能。
em 的优点是它很容易设置最小和最大限制。想象一下你在 23 英寸屏幕上用 vh 或 vw 开发了一些东西,然后在 6 英寸的智能手机上使用相同的代码,这意味着元素会缩小 4 倍。那么在台式机上 24 像素的文本大小在手机上就会变成 6 像素的“隐藏文本”?
还是我理解错了什么?
一个词——简单。em 非常适合这些情况,但通常情况下,使用像素要容易得多。
然而,对于一些开发者来说,额外的麻烦是值得的。
我指的是 em 与 vh,而不是 px 与所有相对单位。
我的意思是,通过使用 em 和基准字体大小,我们可以得到非线性缩放,比如在大屏幕上让文字放大得更慢,在小屏幕上放大得更快。
顺便说一句,px 现在不是也变得响应式了吗?我的意思是,如果你在 iPhone 视网膜显示器上设置 12 像素的字体,它肯定不会是实际的 12 像素,而是会根据 DPI 缩放……
非常棒。
非常酷,我确实看到了对不受层叠影响的响应式文本大小的需求……
有趣的演示,但应该谨慎使用。我认为它主要用于标题缩放,不应该用于段落文本。
1em = 16 像素,浏览器默认的字体大小是一个完全可读的大小。即使更大的尺寸也可以根据所使用的字体很好地工作。
我经常遇到在移动布局中将段落字体大小缩小到 14 像素甚至更小的响应式网站。
较大的行宽 + 较小的字体大小 = 很差的可读性,尤其是因为移动浏览器通常没有工具来增加字体大小。
仅供参考。
这是令人印象深刻的 CSS3 规范中的一项很棒的新工具。
有很多情况下使用它不合适,但你并不需要用你闪闪发光的全新螺丝刀来完成所有工作。继续使用 px、%、(em、ex、ch、rem、cm、mm、in、pt、pc、px)。
我想看看它在 iPhone 上的表现如何。1vh 会是屏幕高度的 1%,还是视窗高度的 1%?
终于!考虑到响应式设计热潮,这在某种程度上是可以预料到的,它应该成为“主流” :) 对我来说有点过时了,很高兴它出现了。
我迫不及待地想看到它得到完全支持……在几年后 :_(
太棒了……
……每天网络都会变得更好一点!
> 用于字体大小,我想它是一个“字母”的大小,但我们知道,在非等宽字体中,字母的宽度是相当任意的。
我猜 em 将是大小的字母。我相信你可以用尺子和放大镜算出来!
我认为我们可以通过使用 em 而不是 px 来实现类似的效果(不完全相同),不是吗?
ems 实际上是相对于其他字体大小的,Jimba。之前没有 CSS 方法可以让任何字体大小相对于其容器的大小。
很棒的技术,但是我发现了一个问题:字体大小对于小型设备来说太小了。因为,当我有一个大小为 13px 的文本时,它对于宽屏设备来说足够大,但也适合移动设备。
但是,如果文本根据屏幕大小进行调整,那么在窄屏上,它最终会变成 8px 或类似的大小。所以你仍然需要在那里调整字体大小。我可能错了,但这是我看到你的视频时想到的第一件事。
我很高兴看到这种转向更灵活的设计。这些年来,固定设计的流行令人痛苦!设计师们终于意识到视窗的大小并不都相同,如果像在纸上一样进行设计,这对许多用户来说是有限制性和令人沮丧的。
最小字体大小怎么办?
使用 JavaScript,这是可能的
http://blog.evolya.fr/public/divers/demo-textsize/demo-textsize.html
(在源代码中)
您可以使用视窗相关的字体大小,而不会影响低分辨率设备上的设计。
使用 CSS 媒体查询,您可以为低分辨率设备提供最小字体大小。
body { font-size: 1vw; }
@media screen and (max-width: 1000px) {
body { font-size: 10px; }
}
这将字体大小设置为视窗宽度的 1%。
例如,在 1280×1024 的情况下,字体大小将有效地为 12.8px。
但是,如果视窗宽度为 1000px 或更小,字体大小将保持在 10px。
例如,在 800×600 的情况下,字体大小将为 10px,而不是 8px,正如您从 1vw 中预期的那样。
如果您使用支持它的浏览器(我使用的是 Google Chrome 的开发版),您可以在下面尝试一下。
例如,将窗口缩小,并在全屏和窗口模式之间切换。
我在博客中使用 FitText,它工作得很好(即使在移动设备上)!但这一个看起来很有希望!感谢分享……
在 FitText 网站上写着
“哦,别让我们发现你在段落文本中使用 FitText。这仅适用于巨大的显示文本!”
很喜欢那个 kkkkkkk
我们什么时候可以在 iOS 或 Android 上使用它?
我几天前做了个类似的东西。
onresize=onload=function(){document.body.style.fontSize=window.innerWidth+”px”}
它是什么?
我喜欢 css3 等等,但是它什么时候能在所有浏览器中运行呢……
很棒的东西。但我不得不说,我想到的这个单位的可能性更多地与动画和图形有关,而不是与类型有关。除了 em 之外,以其他单位指定字体大小的主要缺点是,它几乎肯定会引发用户启动缩放的奇怪行为。这不是用于正文文本,朋友们。让我们不要走这条路。坚持使用 em 和媒体查询。
但能够以视窗宽度的形式指定一个漂亮的动画元素的宽度,而不仅仅是其父容器的百分比,这真是太棒了。更棒的是,你可以混合和匹配高度和宽度:以视窗高度的形式同时指定元素的高度和宽度等等。这里有很多响应式大小的可能性。
太棒了!谢谢。今天在新的开发中实施了它。:)
太棒了。它在 chrome 19 中运行:D
(本周发布)
Chris——玩了更多这个东西,并查看了 W3 规范,我发现了一个明显的遗漏:为什么没有“vmax”单位?只有“vmin”?
一旦人们真正深入研究这些东西,如果您真的要为垂直和水平屏幕设计,您就会知道,总会有一段时间我们希望您在工具集中有它。对于为什么它被遗漏在规范中,您有什么想法吗?嘿——如果浏览器可以原生支持一种比较,为什么不能支持另一种?
快速搜索“vmax css”并没有找到关于这个主题的任何讨论。嗯……
我使用该代码,并在进行 EM 声明后。
真的很酷!虽然我很好奇你为什么使用不同的单位,比如,分别对 h1 和 h2 元素使用 vw 和 vh?根据显示器的方向,h2 的字体大小似乎最终会大于 h1,例如 1920×1080 vs 1080×1920。
使用 Chrome Canary,我没有注意到字体大小对视窗高度的变化作出反应,只对视窗宽度作出反应,所以这可能不是问题。我预计,当视窗变窄时,如果视窗高度保持不变,h2 的大小会保持不变。谢谢。
如果你使用标题元素(h1、h2 等等)来调整字体大小,是不是做错了?从语义上讲,h1 用于表示元素比 h2 或 h3 更加重要,而不是增加字体大小。
是的,请。
从 Modernizr 2.6.2 开始,您可以获得测试
Modernizr.cssvhunit
Modernizr.cssvwunit
Modernizr.cssvmaxunit
Modernizr.cssvminunit
尝试使用它 - 遇到了一个问题
在手机上,当键盘打开时,屏幕高度(设备高度?)发生变化,并且使用 vh 单位的所有内容都会被压缩。不知道如何修复它……至少现在还不行。
@Kseniya:您可以使用以下视窗标签来修复此问题
我在 StackOverflow 上看到了它:div-element-wont-stay-at-the-bottom-when-ios-7-virtual-keyboard-is-present
好的,它可以使用 vh vw 运行……但无法在没有手动刷新/重新加载页面 的情况下完成。
如何使 Jquery 正常工作,这样我就不必使用手动刷新,并且随着窗口比例的调整,文本也同步调整大小???
嘿 Jeremy Lawson,非常感谢你提供的解决方案,使用**媒体查询**为小型设备设置字体大小。
事实上,这正是我想到的第一个疑问:如果“vw”是放大,对于电视屏幕来说没问题,但是小型设备怎么办?字体会很小吗?
我在 Android 上测试了一下,没有注意到任何变化,现在我知道它还没有在 Android 上运行(还没有……)。
所以,看到 CSS3 和 HTML5 的创新速度如此之快真是太棒了。首先我们担心的是智能手机和平板电脑,现在轮到大型电视和智能电视了!
任何寻找纯 Javascript 实现重绘脚本的人可能会发现这很有用
使用视窗单位进行字体大小设置存在可访问性问题,因为它会“覆盖”用户的任何基本字体大小设置! 至少对于桌面浏览器来说,它也会破坏浏览器的缩放功能,这会对可用性产生负面影响!
但仅仅第一点就足以成为永远不要将其用于字体大小设置的理由。
目前我无法想象任何合理的用法。
尤其是在字体大小方面,我们更需要像“最小|最大字体大小”和“字体大小:适合”这样的东西。
以及一个以反比例方式定义值的选项,例如设置链接元素的填充,该填充随着字体大小的减小而增大。
不错! 在看到这篇文章之前,我以为这是不可能的。 我本来想用一张图片而不是文字来替换我的字体类型徽标。 :D 我希望 Android 设备也能尽快支持它。
你可以用纯 CSS 修复 Chrome 调整大小的 bug,使用 vm/vh。 只要@keyframes 动画处于活动状态,UI 就会重绘…
@keyframes forceRepaint { 0% { z-index:1; } 100% { z-index:1; } }
p { animation:forceRepaint 60s infinite; }
值得注意的是,不言而喻,永久重绘 CSS 不适合实际的生产代码,也不是最佳实践。 它只是你可以用 CSS 做的有趣的事情!
Android 现在支持它。 参见:https://caniuse.cn/viewport-units
这太棒了! 不过,我还是希望有一种类似于 flex box 的方法,但应用于文本,即缩放元素的文本内容以使其完全适合父元素。
我还没有机会测试这个,但我认为我可以通过将每个字符包装在
span
中,然后对父元素使用display:flex
来实现相同的效果。 不过这有点像 hack…我怎样才能同时使用 vw 和 vh 来控制字体的垂直和水平大小的 BOTH 高度 AND 宽度,而不是只分别控制宽度 OR 高度?
我发现如果我使用 vw,那么当我只改变视窗的高度时,字体的尺寸不会改变(直到我改变视窗的宽度),反之亦然,使用 vh 并只改变视窗的宽度。
请尽快做一个关于 ACTUAL IOS 设备(至少是 IOS7,我的 iPhone 5 拥有)的 DIFFERENCE 的说明。
IOS7(可能从 IOS5 开始?)渲染的所有内容都大两倍。
VW 基于屏幕的 ACTUAL 像素,即 640,而 IOS 要求我们将所有像素大小提供为如果屏幕有 320 像素。
因此所有东西最终都变大了两倍。
Sergio,那么有没有一种方法可以检测操作系统,然后根据它使用媒体查询来调整大小?
Steve,是的,可以使用媒体查询来定位分辨率,但它不会为你计算不同的补偿。 然后你需要为除 1:1 之外的所有分辨率调整大小
新的 iPhone 是 2:1(普通显示屏分辨率的两倍),还有一些是 1.25、1.3…
我想我接下来的测试将使用一个将大小设置为 VW 的 .parent 容器,然后是一个规则来调整其所有直接子元素:例如
这样我就不必为我定义的每个灵活的字体大小创建 5 条规则(一个主规则和 4 个针对每个分辨率的补偿)
嗯… 在 phonegap 应用程序上尝试过:它不起作用。
事实上,它在 Chrome 的桌面版上运行,但在应用程序封装在 phonegap 中并在设备(Android)上测试时不起作用。
这是一项非常有前景的技术,但需要在各种浏览器和 webview 中得到更好的实现。
如何在 body 上使用这个
font-size: calc(1rem + 2vw);
,它允许非常细微的缩放效果。 可能有一些更好的数学方法,但有人在使用 vw 时提到过 calc 吗?嗨,
reisize bug 现在在 WebKit Nightly 中已修复。
https://bugs.webkit.org/show_bug.cgi?id=87846
嗨 Cris’
我正在寻找一个 CSS hack,它可以让我在互联网上检查时水平压缩字体,但我没有得到这方面的想法。 你能帮我一下吗? 这就像 Photoshop 风格一样,水平压缩字体大小,比如 100% 压缩到 95% 或 85%
请在这方面提供帮助