css
中的单位不少,%
、px
、em
、rem
,以及比较新的vw
、vh
等。每一个单位都有特定的用途,好比当须要设置一个矩形的宽高比为16:9
,而且随屏幕宽度自适应时,除了用%
,其余单位是很难作到的。因此不存在说某个单位是错误的,某个单位是最好的这种说法。css
那本文说的页面适配,指的是一样的布局,在不一样大小的屏幕上怎么进行缩放、控制间距、宽高、字号等大小。html
页面适配的方式有不少:浏览器
px
,结合Media Query进行阶梯式的适配;%
,按百分比自适应布局;rem
,结合html
元素的font-size
来根据屏幕宽度适配;vw
、vh
,直接根据视口宽高适配。在这些大前提下,还需针对一些小的细节作微调。好比使用px
的时候,可能在小屏幕中,要对某个容器进行transform: scale(.8)
,适当缩小处理。使用rem
的时候,须要固定页面的左右间距为10px
等。函数
因此对我来讲,尽管网上曾对px
、rem
和em
等单位的优缺点争论过不少,但个人观点多是,具体状况具体分析。有同窗可能要炸了,你这跟没说有啥区别?工具
对,个人意思跟开篇同样,单论某个单位的好坏是没意义的。咱们最关注的是:什么场景中,使用什么单位最合适。布局
也不卖关子了,我就直接列一些本身以为比较好的实践方式,这些都是根据本身多年的开发经验和大量的调研获得的结论:字体
px
。好比1px
线,4px
的圆角边框。rem
。em
。为何我标题没提到%
、vw
、vh
这几个呢?这几个都是按比例适配,只不过参考对象不同。spa
%
是参考父容器,vw
和vh
是参考视口。他们的使用场景是很是固定的,好比上文提到的16:9
的容器,除了用%
,还有更合适的方式吗?另外,1vw = 1%的视口宽度
。因此就真正须要按视口大小适配的时候再用这个单位吧,使用场景相对固定。scala
接下来我会详细介绍一下这3个结论的由来。设计
em
?em
会叠加计算。在这个机制下太容易犯错了,由于你不知道这段css
指定的字号具体是多少。
// HTML <span> abc <span>def</span> abc </span> // CSS span {font-size: 1.5em;}
实际的效果是这样的:
先要搞清楚em
的计算原理,它是根据当前元素的字号按比例计算的。
外层span
的字号是16px
(浏览器默认值),因此1.5em
以后是24px
。因为字号是继承的,致使内层span
的字号继承过来是24px
,再通过1.5em
以后就成了36px
。
因此,就算要用em
的话,尽可能不要用在继承属性(font-size
)上,除非你真的清楚你在作什么!
好比你想根据字号自动调整字符间距,能够这么作:
.content { font-size: 1rem; letter-spacing: .03em; }
但再仔细想一下,letter-spacing
由.content
的字号决定,而它又由html
的字号决定。那为何letter-spacing
不直接用rem
呢?
px
是我比较喜欢的一个单位,简单又直接。但理性驱使,仍是要合理考虑使用场景。
px
的性质决定了它只能用于固定尺寸。也就是说,若是视觉设计师规定,这个边框宽度必须是2px
。那这种状况下就不须要讨论了。
除了固定尺寸用px
,其余大部分状况均可以使用rem
。
如今考虑一个实际的开发场景,通常来讲都是先有视觉稿才能开发。两种状况:1、假设视觉稿按iPhone 6和iPhone 6+,及其余尺寸各出了一份,那你就按照Media Query去适配。2、设计师只给你一种机型的视觉稿,以iPhone 6为例,750x1334
,2倍屏下转换后是375x667
。
第一种状况也不讨论了,经过Media Query断点适配后,其实你处理的仍是第二种状况。
那第二种的意思是,你要根据宽度为375px
的稿子,扩展到适配任意宽度的屏幕。(页面高度跟业务有关,不用关心,宽度确定是固定的)
接下来拿到视觉稿以下:
测量后主要参数以下:
很快就能写出HTML结构和CSS。
<div class="box box-1">A. 第一段内容</div> <div class="box box-2">B. 第二段内容</div>
body { padding: 10px; background: #f6f0ee; } .box { padding: 10px; font-size: 16px; color: #fff; box-sizing: border-box; } .box-1 { height: 100px; background: #1daedc; } .box-2 { margin-top: 30px; height: 50px; background: #ddbe97; }
完美符合要求。
而后视觉开始提要求了,大屏上要把字体放大、间距放大。
这时候的一个选择是,问设计师是要适配哪一种屏幕,字号是多少,间距是多少。技术上再经过Media Query微调。
@media(min-width: 414px) { // 这里不写了,按视觉要求量化便可 }
另外一个选择能够反过来作。首先按rem做为字号、容器高度、外间距的单位。那么代码能够改成:
html { font-size: 16px; } .box { font-size: 1rem; } .box-1 { height: 6.25rem; } .box-2 { margin-top: 1.875rem; height: 3.125rem; }
其余的样式规则不变,目前的结果和以前的是等价的。若是再加一点魔法,经过Media Query改变iPhone 6+的html
字号,其余元素的属性就会自动变化。
@media(min-width: 414px) { html { font-size: 17.664px; } }
17.664 = 414 * 16 / 375
。
由此能够获得html
的font-size
计算公式为:fontSize = deviceWidth * 16 / 375
;
前提是你的html
有这条meta
属性:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0,user-scalable=no">
至于为什么是16px
,这个后面再介绍。因此rem
有个明显的优势,它能够经过少许代码解决大部分问题。
若是还存在某些细节不够满意,那再用Media Query微调。这种主观的“好看”、“很差看”,可能注定无法自动化解决吧。
关于rem兼容性。桌面端的话仅在IE9+
支持。vw
和vh
同样。因此若是要考虑IE8
的兼容性,那没别的选择只能用px
吧。至于移动端,支持状况不错,能够在生产环境使用。
因为(大部分)浏览器的默认字号为16px
,因此通常来讲把html
的font-size
归一化为16px
是比较合适的实践方式。同时能够参考这篇文章。
为了你们之后参考方便,我列了一些经常使用的Media Query断点(以iPhone 6为基准)。
@media only screen and (min-width: 320px) { html { font-size: 13.65px; } } @media only screen and (min-width: 360px) { html { font-size: 15.36px; } } @media only screen and (min-width: 375px) { html { font-size: 16px; } } @media only screen and (min-width: 390px) { html { font-size: 16.64px; } } @media only screen and (min-width: 414px) { html { font-size: 17.664px; } } @media screen and (min-width: 640px) { html { font-size: 27.31px; } }
你们可能还会看到一些文章中建议把html
字号设成62.5%
。
html { font-size: 62.5%; }
由于刚提到浏览器默认的字号为16px
,用百分比换算后等于10px
,因此CSS
中的rem
是相对于10px
来计算,这样计算的时候很方便,并且能够相对于浏览器的设置来改变文字大小。
那为何要用百分比呢?由于考虑到辅助功能和浏览器设置。对于部分用户,可能会在手机或浏览器的设置中增大手机字号,这意味着对方平时看字是很费力的,因此他才要放大。那把html的字号设置成百分比就很贴心了,会随着手机设置改变页面的字号。
在手机上设置默认字号是很常见的现象,因此若是是一个充满人道主义的排版,我以为用百分比是很是高尚的。它不只从视觉角度去考虑美,更加作到了“用户至上”这四个字。
好,回到现实环境。只有国外那些对Accessibility要求比较高的国家,才会真正去落实这些。但国内的话,老实说,更注重外观的美。历来没有哪家互联网公司的页面会去兼容Screen Reader,也不多作Keyboard Shortcut。
扯远了,就算你看到用62.5%
的状况,有些间距也是不合理的,都作的不太好,特别是把文案作到图片上的,对字号根本不敏感。若是出发点不是为了用户的视觉接受能力,那就别用62.5%
;若是想作,就把缩放考虑到位了,别作半吊子。
另外,针对本小节开头用16px
的状况,这里再给你们提供一招(我调研了一下目前没人这么用,也是灵光一现才想到的)。
用Media Query的缺点是什么?它是分段函数,对于宽度在[320, 360)
区间内的屏幕,会适用同一套方案。最完美的应该是线性函数,怎么作?很简单,用vw
便可。
html { font-size: 4.266667vw; }
用1行代码代替以前6个冗长的Media Query,还不错吧。
咱们来谈最后一个话题。
当你知道html
的font-size
怎么设置后,确定想问,难道我每次写代码时,还得作个除法,把rem
的值计算出来吗?
我相信稍微“现代”一点的开发者,都会用到CSS预处理。基于这个工具,事情就很好办了,以LESS
为例,两步操做以下:
// 1. 按iPhone 6的视觉稿,基准字号为16px,所以能够设置一个LESS变量。 @px: 16rem; // 2. 经过LESS内置的除法自动运算。好比用到16px的字号时,写成16/@px便可,最后会计算成1rem。 .example { font-size: 16/@px; margin: 20/@px 0; padding: 20/@px 10/@px; }
本文给你们介绍了rem
的适配方式,如何设置html
的font-size
,如何更快地书写rem
的值。
本文没有任何“PHP
是最好的语言”这种相似的导向,都是根据本身的经验和观察所得出的结论,如有不对请指正。
页面适配是很精细的工做,可能你已经有了一套很是熟练的开发方式,那保持下去便可。若是没有,不妨参考一下这篇文章。