几年前,流体排版 的概念被提出。主要思想是,如果您知道在两个不同的视窗大小下字体的尺寸,那么就可以让字体在这两个尺寸之间平滑缩放。我们在 FitText (当然,指的是标题) 中使用了一个 jQuery 解决方案,直到 calc()
函数发布,为我们提供了一个纯 CSS 解决方案。
p {
font-size: calc(16px + (24 - 16)*(100vw - 400px)/(800 - 400));
}
这里最重要的数字是 24px (高达 800px 视窗的较大的字体) 和 16px (低至 400px 视窗的较小的字体大小)。在这个上下文中,我不会使用“最小”或“最大”来描述字体大小和视窗,因为这有点误导。实际上,您仍然需要为小于 400px 和大于 800px 的视窗提供默认字体大小 - 否则,字体将随着方程式相同比例的缩放而不断变小(或变大)。或者,如果您喜欢,可以为更大的屏幕尺寸定义另一个比例。
它运行良好,您应该仔细检查背后的数学原理。
填充和行高?
我非常喜欢流体排版的概念,于是开始思考它是否可以应用于其他属性。答案是可以!您无法使用百分比,但只要坚持使用 px、em 或 rem 单位,就可以了。我更喜欢使用像素,因此我所有的实验都使用像素,但是有一个 很不错的生成器 可以帮助您进行转换(如果您需要)。
所以,回到 padding
和 line-height
。使用相同的 calc()
逻辑,我们可以实现一个完全流动的 *布局*,在定义的屏幕尺寸下具有固定值。

我在 这个网站 上实现了这个想法,但只将其应用于 font-size
和 line-height
。是的,随着您使用它,您会越来越容易忽略所有这些数学运算并直接应用它们。
关于“Hero”组件的延伸
如果您像我一样,那么您可能对我们都已知为 hero 组件 的东西有所争议。它无处不在,已经成为像 Bootstrap 这样的设计系统中的一个基本元素。

我主要的问题是关于使它们响应式的最佳方式。如果它不是一个 *全屏* Hero (即在任何尺寸下都占据整个视窗),那么我通常会问设计师页面应该如何表现。通常,Hero 页面的比例很好,这样我就可以使用 padding-bottom
以百分比形式,并对内部内容进行绝对定位。这种方法在大多数情况下都能奏效,
这很有趣,效果很好,尤其是在网站的桌面版本上。您最终会得到一个整洁的 Hero 部分,比例很好,内容居中。
但是,当您开始缩小视窗时会发生什么?Hero 在一定程度上仍然可读,您确实需要更改比例。
假设我们正在使用桌面优先的响应式方法,我们可以从一个水平矩形开始,向下缩放,直到在小屏幕上只剩下一个垂直矩形。

这是一个 PITA,因为您最终可能会写很多行 CSS 代码来使 Hero 部分在不同的断点上看起来很好且可读。
一定有更好的方法,对吗?如果 Hero 在页面宽度变窄时可以增加高度会怎么样?
回到流动性!
因此,我回到了 calc()
函数,它在其他情况下有效,例如让浏览器处理数学运算,并根据视窗的变化相应地缩放内容。
这是我们从流体排版示例开始的 CSS 代码
p {
width: 100%;
max-width: 1200px;
margin: 0 auto;
font-family: 'Open Sans', sans-serif;
font-size: calc(24px + (18 - 24)*(100vw - 400px)/(1200 - 400));
line-height: 1.5;
padding: 10px;
}
我们想要的是:一个 Hero 组件,当您缩小页面时,它会变得更大。我使用像素单位表示 *流动部分*,并在其他地方使用百分比。

这是一个关于我最终得到的解决方案的屏幕截图
当您想要为文本提供更多垂直空间时,这很有用。从大到小缩小视窗宽度最终将为相同文本提供更多行,因为字体大小不能太小。
相当不错,对吧?calc()
又一次证明了它可以解决我的问题。
是的,有一些注意事项
浏览器支持非常好,几乎覆盖了 93% 的用户 (在撰写本文时),主要例外是 Opera mini。
这些浏览器支持数据来自 Caniuse,其中包含更多详细信息。数字表示浏览器从该版本开始支持该功能。
桌面
Chrome | Firefox | IE | Edge | Safari |
---|---|---|---|---|
19* | 4* | 11 | 12 | 6* |
移动设备/平板电脑
Android Chrome | Android Firefox | Android | iOS Safari |
---|---|---|---|
127 | 127 | 127 | 6.0-6.1* |
此外,请记住,这种 calc()
技术仅支持 px、em 和 rem 单位。但是,由于 Hero 通常宽度为 100%,因此我们在此处介绍的示例很容易将 padding-bottom
百分比之类的单位转换为像素。
哦!还要记住,在 calc()
函数中的断点之前和之后重置您的值。否则,您最终可能会为目标属性获得非常大或非常小的值。
您怎么看?
这可能只是我们处理这种情况的一种方式,它主要由我对 calc()
函数的兴趣驱动。因此,这引发了一个问题:您是如何处理缩放 Hero 组件高度的?您是否已将 calc()
应用于此?您是否更喜欢在不同的宽度下处理断点?您是否使用了其他方法?在评论中告诉我吧!
您一定要看看这篇博文中关于 calc 和 vm 的使用。 https://medium.com/@jakobud/css-polyfluidsizing-using-calc-vw-breakpoints-and-linear-equations-8e15505d21ab 这确实是一个启示,我将 poly 流体方法用于类型,也用于组件/元素,一切都能流畅而完美地流动。
这种方法也教会了我从不同的角度来看待设计需求。也就是说,我了解了在 vw 320 和 vw 1024 下事物应该是什么样子,但在这两个图像之间,大多数情况下,由我来决定事物在这两个点之间如何缩放,而 poly 流体尺寸正是完成这项任务的好方法。
我之前写过一些比例大小的 Hero 元素,不需要所有这些数学运算或断点。
可能有些情况更适合使用您的方法,但从拥有所有这些额外的代码中也获得了额外的复杂性,而这些代码可能并不总是必需的。
我还在一个团队中工作,需要将我的样式传递给其他团队成员,如果我传递了像这样复杂的计算,可读性/易理解性就会成为问题。
嗨,Timothy,感谢您的后续回复。问题是,使用您的代码,Hero 在您缩小页面时会变小。我的目标是在缩小页面时让它更高。如果您想在没有媒体查询的情况下进行操作,可以执行以下操作
很明显,如果您需要更简单的方案,则不需要使用 `calc()`,但据我所知,没有其他(简单)方法可以让元素在页面缩小时变大。
为什么要将可读内容绝对定位?与其为图像背景设置高度,不如让内容控制高度,这样您就不需要任何 calc。
使用网格/弹性盒子和 `place-content: center`,并设置 `min-height`(如果您喜欢),以及一些填充以美化。然后,在任何断点上都不需要任何高度。我认为您把事情复杂化了。
嗨,Vanderson,我同意这是一种边缘情况。主要思路是将 `calc()` 与“反向值”一起使用,以便在页面缩小时,元素变大。但是,如果我需要英雄组件在屏幕尺寸大于 x 时保持比例呢?
这可能是一个很大的技巧,但无需任何媒体查询,您可以使用弹性盒子将英雄的高度设置为内容舒适地适应时的固有纵横比,当内容不适应(较小的屏幕)时,内容高度将设置英雄高度。基本上,在任何给定的屏幕尺寸下,较高的元素获胜。我所知道的唯一缺点是,您需要一个空 div(空格)才能在所有浏览器(包括 IE)中正常工作。
我喜欢这种方法,因为您不必了解或限制任何屏幕尺寸下的内容数量,并且它可以应用于各种组件,而不仅仅是英雄——分割列、画廊等。它只是可行。
我还没有深入研究原因,但流体排版示例在 Safari 中不起作用。(v.12.0. 在 MacOS 10.13.6 上)
人们调整浏览器大小的频率有多高?移动用户不调整,Windows 用户将浏览器最大化,Mac 通常设置为一个最喜欢的尺寸。唯一会进行调整的人(我知道)是测试不同视窗的开发者。
嗨,Michail!绝对没错,唯一会调整浏览器大小的人是我们开发者:) 但由于您无法预测用户将拥有的屏幕的实际尺寸,因此我认为最好涵盖所有尺寸。因此,我们花费大量时间调整浏览器大小。
在移动设备和平板电脑上,有些人会偶尔以横向模式浏览内容。在纵向和横向之间旋转设备类似于调整桌面浏览器的尺寸。
“记住在 `calc()` 函数中的断点前后重置您的值。”
您能详细解释一下,或者举个例子吗?
嘿,Martino!这是一种很棒的技术。从没想过将流体排版方法应用于其他属性。
将它应用于填充和行高似乎有点过度(我会分别使用 `em` 和无单位),但我非常喜欢“英雄”组件的响应式高度。赞赏。
为什么使用绝对定位而不是弹性盒子来居中元素?
我想看看使用弹性盒子而不是绝对定位的这种技术。
我一直使用 https://websemantics.uk/tools/responsive-font-calculator/ 来生成流体类型,它非常棒,可以避免很多麻烦,节省很多时间。
谢谢!
您能更详细地解释公式背后的数学原理吗?例如,假设我想要一个较短的流体英雄。
不错的文章,感谢您提供的公式,它在大多数情况下都能很好地工作。
我已经玩过它,并创建了一个小 scss-mixin 来测试和简化使用、编辑…
我真的很讨厌那些在较小屏幕上将字体大小设置得更小的网站。这毫无意义!如果真要改变,字体在移动设备上应该更大。
移动设备上的像素本来就更小。这些“流体排版”技巧通常只是开发者用来炫耀其“响应式”技能的方式。
这难道不是实现问题而不是方法问题吗?
完全正确。因此,我会反其道而行之。曲线通常从大(小屏幕)到中等(中等屏幕),然后在超大屏幕上返回到大。人们没有意识到,在字体大小易于阅读的情况下,获取信息是多么容易。我只想鼓励开发者大胆一点,在最小的屏幕上不要低于 18 像素。我到目前为止的经验是,起初这看起来很大,但是当你习惯了它,然后发现一个在 320 像素宽的屏幕上字体大小为 12 像素的网站时,你真的需要眯起眼睛才能读懂内容。要么做得很大,要么不做!;)
我之前尝试过类似的东西,结果我对控制移动设备的纵横比、桌面设备的另一种纵横比,然后使用 Calc 在两者之间切换很感兴趣。我使用元素的高度来实现,并使用 `min-` 和 `max-` 来设置我的“锁定”:https://codepen.io/jhogue/pen/ZpNqZm
各位,请停止使用 vw、vh 单位来设置字体大小(只有在极少数情况下需要这样做),我知道很多开发者不幸地开始使用这种技巧,它会导致很多问题,在不同的设备上表现不佳。
如果您将字体大小定义为像素值,它在小尺寸的全高清移动设备屏幕上不会是 16 像素大小。
移动设备上会发生这种魔法。像素默认情况下会转换为厘米和毫米。
https://www.unitconverters.net/typography/pixel-x-to-centimeter.htm
如果您发现某个屏幕需要所有内容更大或更小(例如智能电视浏览器),只需使用媒体查询进行缩放调整。
如果您的屏幕是这样的
https://www.overclockers.co.uk/aoc-agon-ag352ucg-35-3440×1440-ips-g-sync-100hz-widescreen-ultrawide-curved-led-monitor-black-si-mo-04f-ao.html
并且字体大小基于 `vieewPortWidth`,它会变得非常大,页面会显示错乱。
如果您确定希望所有屏幕上都显示相同大小的字体,请使用厘米或毫米值,这样它永远都是。这不是 CSS 技巧,而是您正在使用的 CSS 技巧。