[翻译]使用VH和VW实现真正的流体排版
前言
不像响应式布局,通过media query,设置几个变化点来适配,流体排版通过调整大小,适配所有设备宽度。这个方法可以使我们开发的网页,在几乎所有屏幕尺寸上都可以使用。但出于一些原因,它的使用率还远远没有响应式技术高。
在印刷的历史上,排版是根深蒂固的。关于“流体”的概念,在传统思想里并不存在。这是因为,在印刷上,尺寸大小都是有固定的,不用考虑在页面上使用。我认为流体排版技术可以和网页很好的匹配。这是在不同媒介上的一种解决方法。
并不意味着我们要推翻之前的所有关于排版的认识,只需要去学习如何用不同方式,去运用掌握新的技术。只要注意细节,就可以制作出适配所有屏幕尺寸的完美的页面。
流体排版上手
视口(viewport)单位,使流体排版在页面上应用变为可能。视口单位是根据浏览器的视口尺寸的百分比来定义的。
举个例子,1视口宽度(vw)等于视口宽度的1%,它不同于百分比的地方是,它的宽度是依赖于视口的宽度的,而百分比是元素的祖先元素来决定的。
视口单位,不同于其它单位,它不依赖于基础字体的大小。这种差别很重要,使它变得有意义而且独特。
可以使用的4种视口单位:
- vw:视口宽度(viewport width)
- vh:视口高度(viewport height)
- vmin:视口宽度或高度,选择小的那个
- vmax:视口宽度或高度,选择大的那个
使用流体排版最简单的方法,是把html元素的font-size,设置为一个流体单位:
html{ font-size: 2vw; }
这个例子中,我们把根元素的字体大小设置为2vw。这里我们已经修改了根元素字体大小。因为直接或间接使用的em或rem单位,都是依赖于"root rem"的,所以也变成流体的了。例如
h1{ font-size:2em; }
h1的font-size:2em,如果它依赖的是根节点的字体大小,那么 font-size:2*2vw=4vw。
只使用视口相关的单位也有一些不足。
- 无法精确地控制放大比率。
- 没有最大或最小字体大小。
- 和使用font-size相比,用户更容易使用像素来声明大小。
控制视口单位来设置最小最大font-size
html设置为font-size:2vw的方法,看起来既是流体的,调用起来也很方便,但有些场景没法覆盖。视口单位不是万能的,它也需要使用一些其它的方法,来解决无法覆盖的场景。由于视口单位都是依赖于视口的,在非常小的屏幕上,会得到很小的字体大小,已致无法查看。(chrome的最小字体是12px,好像可以解决了。)
理想情况下,我们可以通过设置最小字体来避免这种情况,但CSS中没有min-font-size这个属性。通过一些横向思维,我们可以得到实现这种效果的方法。
首先,我们可以使用calc()表达式。
html{ font-size: calc(1em + 1vw); }
这样就算我们在一个0宽度的视口中,font-size的大小也会存在,并为1em。在大的屏幕上,1vw也会在最小字体1em的基础上增加。但是这种解决方法也不是最理想的。通常我们只是想在一些小的屏幕上去设置最小字体。我们可以使用media query来解决:
@media screen and (min-width: 50em) {
html {
font-size: 2vw;
}}
上面代码设置,是仅在当视口宽度大于50em的时候,使用流体。虽然这样能很好的工作,但也表明会在固定值和流体值之间跳动。为了解决这个问题,我们可以计算出流体值和固定值之间的对应关系。
如果默认字体大小是16像素,并且2vw是2%的视口宽度,那么可以知道在800像素的视口时两个值是相等的。(16/(2/100)=800)
因为我们想在media query中,使用em单位来匹配。现在来换算一下像素到em。800像素除以16:800/16=50。我们也可以使用这个公式来算1/(2/100)=50。和上面例子里使用的变化条件一样,2vw对应的是50em。最终,我们得到了一个不会在固定和流体之间,产生跳动变化的值。
同样的可以用公式去算出最大字体。如果我们想使用的最大字体是24像素,那么对应的视口宽度就是24/(2/100)=1200px。换算成字体,就是1.5/(2/100)=75em。如果视口宽度大于75em时,我们就把字体大小设置成固定值。
@media screen and (min-width: 75em) {
html {
font-size: 1.5em;
}}
这些计算都不是太难,下面做了一个表格,显示了各视口宽度,流体大小对应的字体大小。
通过这个表格,你可以获得一些控制视口单位变化。使用单独的视口单位,可以只看对应的一列中的字体大小。
控制缩放比率
在不使用media query的情况下,我们不可能解决,在400像素的屏幕上显示16像素的字体,在800像素显示24像素的问题。
还有,你可能会说,可以使用设置最大最小字体的方式,来解决这个问题。但这里不是像那样来处理的。
我们要怎么去解决这个问题呢?答案是使用calc()。使用calc和视口单位配合,我们可以用高级的流体排版,可以精确地控制一定范围内的视口宽度使用特定大小的像素值。这里需要建立一个基本的数字函数:
这个函数可以能过一个范围内的一个值,可以计算出另一个对应范围的值。如果你取1-100的中的50,用它获取1-200的值 ,你将得到100。(其实我得到的是(1+(200-1)*(50-1)/(100-1)=99.4949495))。这两个值都是各自范围的中间值。
这是一个求映射值的工具函数,在JS中处理数据时经常使用。当我认识到这只是一个纯粹的数学函数,我只需要一个变化的量,我使用calc()来运行这个函数。这里的变化关键值是视口大小:视口大小就是一个变量。100vw是一个变化的值,它是根据视口的尺寸变化的。有了最终的设想,花了一段时间来获得了能工作的函数表达式。calc()函数以其独特的方式来处理不同的单位类型。如果你对这方面感兴趣,强烈推荐《 W3C对单位类型和值规范》,不为别的,就为了你在同事之间沟通时,可以吹牛B。
计算看上去很复杂,其实很简单。我们选择最小和最大字体值,并且可以根据屏幕的尺寸来获取精确的字体大小。我们可以使用任何单位,包括em,rem,px。这里拿像素来举例,是因为可以解释起来更方便并更好理解,但正常工作中我是使用rem单位的。看你自己的喜好啦,但有一点,方程式里所有的值必须是单位统一的,而且你也要像上面的例子中一样,去除一些单位。
如果你不想输入上面的代码,有一些工具可以帮助你实现。比如:SASS,LESS,PostCSS插件。这样你就可以轻松的工作了。
保持理想的阅读长度
在《The elements of typographic style》,Robert Bringhurst 提出一个合理的阅读长度 大约是45到75个字符的长度
Anything from 45 to 75 characters is widely regarded as a satisfactory length of line for a single-column page set in a serifed text face in a text size. The 66-character line (counting both letters and spaces) is widely regarded as ideal.
同样的规则可以直接运用到流体排版上,很多情况下,文件缩放实现一致的阅读长度是可能的。
在响应式方法里,我们在media query里设置不同的字体大小,调整容器的宽度,来保持正确的阅读长度。然而,使用流体排版,调整media query下的值方法已经行不通了。 只是设置容器的大小,使它的比率和字体相同。我们可以使用像上文提到的计算font-size的方法,使用 calc()来计算width属性的值。这可以保持阅读长度-而且样式表也更容易阅读和维护了。
在非常小的屏幕维护理想的阅读长度是不可能的。这种情况下,我们选择把容器的宽度设置为智能移动设备的宽度。
实现模块化缩放
模块化缩放是指一组成比例的数值。看图可以更直观地看到效果:
每个标题都是下面标题的1.2倍大小。
不用的屏幕尺寸显示不同的绽放效果会更好。
在小屏幕的时候,标题大小显示得更统一。在大屏幕上有足够的空间可以显示更大的差别。我们可以使用排版技术来使在不同的模板缩放变化时更平滑。简单地在不同的屏幕上选择不的缩放比率,然后计算出每个的标题级别,不同的最小和最大的字体大小。
计算模块化的缩放,使用基础字体大小乘以一个期望的比率来得到一个大的值。得到小值是用除法。使用相同的方法去计算出每个缩放对应的值。
大值:
- 1em × 1.125em = 1.125em
- 1.125em × 1.125em = 1.266em
- 1.266em × 1.125em = 1.424em
- 1.424em × 1.125em = 1.602em
小值:
- 1em ÷ 1.125em = 0.889em
- 0.889em ÷ 1.125em = 0.790em
- 0.790em ÷ 1.125em = 0.702em
- 0.702em ÷ 1.125em = 0.624em
我们使用1.125做为我们最小缩放比率,1.250做为我们最大缩放比率。下面我们把这个缩放比率应用到每个级别的标题级别上。
- 最小缩放比:1.125
- 最大缩放比:1.250
让我们在codepen上演示一下流体模块缩放标题。你可以从Tim Brown的《排版的意义》是去了解更多的模块绽放信息。
如何去选择一个合适的缩放比率,推荐 Jeremy Church的网站Type Scale,Tim brown、Scott Kellum的Modular Scale网站
保持垂直比例
纵向排版有必要保持页面元素之间的空白一致。这方面信息可以读Espen Brunborg的《CSS Baseline: The Good, the Bad and the Ugly》。
在我们的层上保持纵向排版,需要设置一个元素之间的垂直空白的比例。找到一个在大屏幕和小屏幕上都适配的垂直排版,是很有挑战性的。我们通常希望找出大屏和小屏的基本度量,或使用不同的比例。
在流体排版中,基线也像字体大小一样是流体的。事实上,你给根元素设置一个流体的值,你可以使用em或rem单位。你也可以使用calc()来计算。
我们设置baseline为1.5rem,然后把body的padding设置为一个单位的baseline。
body {
padding: 1.5rem;
}
可以同样来设置line-height和margin
p {
line-height: 1.5rem;
margin-bottom: 1.5rem;
}
给标题元素设置不同的line-height。我想让line-height加margin值等于baseline的增量。这里可以使用calc()来计算。
h1 {
font-size: 2rem;
line-height: 2rem;
margin-top: calc((1.5rem - 2rem) + 1.5rem);}
这个例子里,标题元素的height加上margin值等于3rem,正好是baseline值的两倍。
这里用sass变量创建一个例子,方便大家理解。
未来,使用自定义css属性,可以对这项技术进行更多的扩展。我们能在calc()表达式中,使用css变量,计算出对应media query中的baseline基值。
约束条件
当你想在WordPress或Bootstrap,这些已经有预定义的布局中使用,或在已经存在布局的网站上使用,流体排版时。容器有可能不是流体的,或它们不是根据字体大小的比率来改变的。
最近,帮助澳大利亚政府的民众部,实现了流体排版。这是一个很大的网站,而且我必须根据已有的设计进行制作。在这种大流量的网站上实现流体布局,我有两个主要方面的问题。
第一问题,怎样阻止布局被破坏?在这个项目中,我预期导航容器里的内容,会因为字体大小和窗口的改变的比例不同而溢出。但很神奇的是,并没有出现这个问题。
实际情况,正好相反。之前需要单独设置来调整的地方,内容很自然的适配了它的容器。总之,样式表中需要尽量少的media query,大多的组件需要更少的样式声明。
还有一个好处是,我们可以不用单独为平板设备去制作一个单独的版本,因为这已经可以很好地在小屏幕上工作了。
下面是在过去需要去为每种不同屏幕尺寸调整一个版本的导航组件。虽然在小屏幕下表现还是不太完美,但可以不破坏它的整体性和功能性。
第二个问题,因为里面有很多的固定宽度,所以无法保持每行的字符都有理解的阅读长度。我在手机和平板电脑上,对字体大小进行了调整,使其保持在理想的阅读长度--移动设备阅读更重要。
主容器和文本的缩放比是不同的,当浏览器改变大小时,一些文本会重新排列。因为我不想在设备改变方向时,导致阅读处置改变。这是无法避免的情况,我们只能去测试一下主要设备的影响情况。还好,在移动设备上重排的影响并不是太大。
最后,我们对结果满意。毫无疑问,可以做更多关于排版的改进,我们已经提高了网站的可读性。随着流体排版的经验越来越多,在下一个设计迭代中,主要的焦点会集中在排版和可读性上。
在现有网站上,使用流体排版技术的几点提示:
- 根据你的设计来,确定最适合你的字体的最大最小值及缩放比。
- font-size使用em单位。如果你想在一个部分容器上(如导航),使用流体排版,给容器设置一个固定值。在这个容器中的em值,都是依赖于固定值的。
- 同样的,如果你只是把主体容器设置成流体排版。如果你把一个块容器的字体设置为流体的,那么所有这个容器中的em值都是流体的。
- 文本重排,如果只是在浏览器改变大小时,或设备改变方向时发生,不用过于在意。
- 维护一个好的阅读长度是可能的。优先去考虑,手机或平板设备的理想阅读长度。
浏览器支持情况和BUGS
经常听到在Safari和特别是移动版的Safari,在同时使用视口单位和calc()表达式时,会出现明显的bug。但都没有提出什么具体的问题是什么,所以这里做了一些测试。
单独测试了calc()表达式和视口单位,以及同时使用它们来实现流体排版技术。在使用些技术时,没有发现什么问题。
在现代浏览器中,calc()和视口单位都能很好的工作。
在Safari 8以下和ie 11以下浏览器,当窗口中浏览器改变大小时,calc()表达式中的视口单位,不会重新计算。
可以通过media query来加以修正。
/* Older browsers */
html { font-size: 16px; } /* Modern browsers only need this one */ @media screen and (min-width: 25em){
html { font-size: calc( 16px + (24 - 16) * (100vw - 400px) / (800 - 400) ); }
} /* Safari <8 and IE <11 */
@media screen and (min-width: 25em){
html { font-size: calc( 16px + (24 - 16) * (100vw - 400px) / (800 - 400) ); }
}
@media screen and (min-width: 50em){
html { font-size: calc( 16px + (24 - 16) * (100vw - 400px) / (800 - 400) ); }
}
设置了Safary 8以下和ie 11以下,通过media query来重新计算字体大小。
老的浏览器则能过js来监听窗口的改变事件来重新计算字体大小。
可以在caniuse和查看支持情况
使用流体排版
如果要使用流体排版,要先想清楚要使用哪种解决方案。
如果整个设计都是流体的,可以考虑使用rem来定义流体,可以声明html字体大小为一个流体单位。可以使用em和rem来定义所有设计部分。
小心选择你的最大最小字体。关于这点,你需要决定是否直接使用视口单位或对更加精确地缩放比率。如果是后者,使用Sass,LESS或PostCSS插件中的函数,可以更简单实现。
确保获得了正确的字体的最大最小值。这是问题的关键。一旦你选定了根元素的字体大小,其它的所有组件都是依赖这个值来计算的。项目中如果后面要调整这个值,那么整个项目都要调整。
不要忘记,在使用流体排版之前定义一个默认的字体大小。默认字体大小,用来在那些不支持流体字体大小的浏览器上使用的,这个值不需要和字体最小值 相同。
最后,考虑你的设计上的限制,如何去解决像标题级别和阅读长度的问题。可以参与文中的处理方法。如果你的标题组件,想和常规的文本,以不同的比率进行缩放,在添加calc()表达式之前,先考虑可读性和样式代码的可维护性。
我希望这可以给你启发,可以让你思考在下个项目中那里可以用到流体排版。
基本阅读:
- “Fit to Scale,” Trent Walton
- “Fluid Type,” Trent Walton
- “Viewport Sized Typography,” Chris Coyier
相关阅读:
- “Responsive Typography With SASS Maps,” Jonathan Suh
- “Benton Modern: A Case Study on Art-Directed Responsive Web Typography,” Marko Dugonjić
- “Advanced Web Typography: Responsive Web Typography,” Elliot Jay Stocks
扩展阅读:
- “Everything I Know About Responsive Web Typography,” Zell Liew
- “Responsive Typography With REMs: How to Build a Scalable Typographic Foundation in Three Steps,” Max Luster
- “Fluid Typography for Responsive Websites,” Ana Sampaio
- “Responsive Typography,” Responsivedesign.is
原文:Truly Fluid Typography With vh And vw Units
原文链接:https://www.smashingmagazine.com/2016/05/fluid-typography/
[翻译]使用VH和VW实现真正的流体排版的更多相关文章
- CSS 中的rem,em,vh,vw一次说清楚
关于css中的长度单位,我们用的最多就是px,因为他简单直接.但是当一套方案匹配不同终端时,px就会显得过于生硬,不容易变通. 然而rem,em,vh,vw就可以有效的解决这一问题.让我们来看看这些东 ...
- vh、vw、vmin、vmax 知多少
介绍一些 CSS3 新增的单位,平时可能用的比较少,但是由于单位的特性,在一些特殊场合会有妙用. vw and vh 1vw 等于1/100的视口宽度 (Viewport Width) 1vh 等于1 ...
- css 单位px、em、rem、vh、vw、vmin、vmax区别
1.px:相对长度单位.像素px是相对于显示器屏幕分辨率而言的. 2.em:相对长度单位.相对于当前对象内文本的字体尺寸.如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸. 看下面 ...
- 认识 vh 和 vw 单位
1. 页面 html 结构 <header> <h1>欢迎来到米修在线</h1> <p>Lorem ipsum dolor sit amet conse ...
- Css3中自适应布局单位vh、vw
视口单位(Viewport units) 什么是视口? 在桌面端,视口指的是在桌面端,指的是浏览器的可视区域:而在移动端,它涉及3个视口:Layout Viewport(布局视口),Visual Vi ...
- 深度解析使用CSS单位px、em、rem、vh、vw、vmin、vmax实现页面布局
1.px:绝对单位,页面按精确像素展示 2.em:相对单位,基准点为父节点字体的大小,如果自身定义了font-size按自身来计算(浏览器默认字体是16px),整个页面内1em不是一个固定的值. e ...
- CSS3中的vh、vw及其应用场景
需求:我们项目的需求是 一.vh vw vw和vh是相对于视口(viewport)的宽度和高度.由于现在移动设备的屏幕尺寸之差别,如果仍然根据屏幕的物理分辨率来设计网页,效果很难统一,因此html ...
- 移动端的vh 和 vw简介和使用场景
vw 相对于视窗的宽度:视窗宽度是100vw:vh则类似,是相对于视窗的高度,视窗高度是100vh. 这里的视窗指的又是啥? 是浏览器内部宽度大小(window.innerWidth)? 是整个浏览器 ...
- vh搭配vw进行响应式布局
1.浏览器兼容性: IE8-不支持,IOS7.1-不支持,android4.3-不支持 2. vh代表浏览器视口高度(100vh等于当前浏览器的整个高度) 3.vw代表浏览器视口的宽度 (100vw等 ...
随机推荐
- IntelliJ IDEA 2017.3/2018.1 激活
传统的License Server方式已经无法注册IntelliJ IDEA2017.3的版本了. http://idea.lanyus.com,这个网站有破解补丁和注册码两种方式,另外http:// ...
- node.js中ws模块创建服务端和客户端,网页WebSocket客户端
首先下载websocket模块,命令行输入 npm install ws 1.node.js中ws模块创建服务端 // 加载node上websocket模块 ws; var ws = require( ...
- Rpgmakermv(31)MOG插件与YEP的结合
问题简述: 因为我在开发时使用了gamequestsystem(任务插件),所以必须使用YEP_mainmenumanager; 此时,我又想加个MOG_Picture插件(图片收集插件): 当他们在 ...
- Sitecore CMS中更改项目的模板
如何在Sitecore CMS中创建项目后更改项目的模板. 在创建项目时选择了错误的模板,或者创建了新模板并将现有项目更新为新模板时,这非常有用. 警告! 更改模板时要小心.如果原始模板具有不在新 ...
- samba共享目录无法访问的一般解决方案,非用户登录和读写权限问题
配smb,被第四点坑了很久,特此转载. 由于这5点都是比较普通的情况,不涉及用户登录和读写权限问题 1)关闭防火墙: #sevice iptables stop 2)修改 /etc/samba/smb ...
- python seek()方法报错:“io.UnsupportedOperation: can't do nonzero cur-relative seeks”
今天使用seek()时报错了, 看下图 然后就百度了一下,找到了解决方法 这篇博客https://www.cnblogs.com/xisheng/p/7636736.html 帮忙解决了问题, 照理说 ...
- Linux上查看大文件的开头几行内容以及结尾几行的内容
head -n 50 filePath 查看开头50行的内容 tail -n 50 filePath 查看文件结尾50行的内容
- window下nodejs用nodemon启动koa2项目(用cmd启动不了,要用Git Bash Here 启动才可以)
window下nodejs用nodemon启动koa2项目(用cmd启动不了,要用Git Bash Here 启动才可以)nodemon --watch 'app/**/*' -e ts --exec ...
- 搭建Vue2+Vuex+Webpack+Pug(jade)+Stylus环境
一.开发环境配置 开始之前,假设你已经安装了最新版本的 node 和 npm. 全局安装 vue-cli 和 webpack : npm install vue-cli webpack -g 创建工 ...
- 大数据自学6-Hue集成环境操作Hbase
上一章讲过,Hue集成环境是可以直接操作Hbase,但是公司的环境一直报错,虽然也可以透过写代码访问Hbase,但是看到Hue环境中无法访问,还是觉得不爽,因此决定再花些力气找找原因. 找原因要先查L ...