前两天有个朋友问起关于rem的一些问题,让我有些在意。因为随着CSS3的逐渐成熟,在优雅降级/渐进增强原则的保障下,很多CSS新特性已经不在是试用特性,而是在Web设计中得到广泛推行和应用!而CSS3新增的单位rem也在其列,当朋友问起时,我才意识到自己对这个单位也并不是很了解,趁着周末有些闲暇时光,不妨给自己的大脑充充电。
定义
Equal to the computed value of font-size on the root element. (W3C)
直译是“与根元素的字体大小相等”,当然也有一种更直接的理解 root em 。我们知道在HTML中根元素其实也就是 <html> 元素,所以rem单位其实是相对于 <html> 元素的字体大小而言的。
场景
为了方便说明rem单位的功效,我们先来构造一个很常用的页面结构,然后分别使用px和rem在对比实现。通常我们在制作博文阅读页面的时候都会先将博文的标题(h2.article-title)显示,然后后面紧跟丰富的博文内容(div.article-body),最后可能还会在博文的尾部(div.article-foot)显示作者或发布时间等等。而为了让文章的结构更为清晰,我们一般会将文章的标题放大突出显示,而结尾可能也会做缩小弱化处理,大致结构如下:
1 2 3 4 5 6 7 8 9 |
<div class="article"> <h2 class="article-title">这是文章的标题</h2> <div class="article-body"> 我通常把文章内容放置在这里。<br>这样看起来比较舒服。 </div> <div class="article-foot"> 发布人:MrZheng 发布时间:2015/11/08 </div> </div> |
我们可能希望在页面上显示的效果是这样的:
我们这里不去关心布局,只看字号:标题18px,内容14px,尾部12px。接下来我们来看看如何分别使用px和rem来实现预览样式。
px VS rem
首先是使用px实现:
1 2 3 |
.article-title {font-size: 18px;font-weight: normal;} .article-body {font-size: 14px;margin: 10px 0;} .article-foot {font-size: 12px;} |
然后,我们看看rem版本:
1 2 3 4 |
html {font-size: 10px;} .article-title {font-size: 1.8rem;font-weight: normal;} .article-body {font-size: 1.4rem;margin: 10px 0;} .article-foot {font-size: 1.2rem;} |
为了验证rem单位最终在浏览器上显示的字体大小确实是预设的18px,14px和12px,我使用Chrome调试工具在Elements面板的Computed面板查看了结果:
好了,说明rem最终实现的效果确实可以达到和直接使用px一样的结果。但是单从上面的代码来看,我们发现使用rem其实比使用px需要更多的代码,而且也并没有发现其他什么优势,那么CSS3为什么会增加这个单位呢?
rem的优势
我们从上面的代码中可以发现,在使用rem的时候,我们给标题、内容、尾部设置字体的时候使用的是一个小数,而最终我们在浏览器中看到的却是我们需要的18px、14px和12px,结合定义部分提到的rem是相对于根(html)元素计算的,那么就好理解了,以标题为例: 10px * 1.8 = 18px 。所以,rem的优势便不言而喻了,可以通过修改html元素的font-size直接控制整个网站的字体乃至其他尺寸属性的值的大小(诸如:margin,padding等)。
那么,有人可能会问:我的网页放在那里显示得好好的,我没事改什么字体大小,调什么间距?即便久了我想换换风格,那也可能改改颜色,换换布局,跟这尺寸单位压根儿没多大关系吧?
其实并不是这样的,我来给大家说两个情况。
第一,我们做网页,要考虑到访问我们网页的各个群体。要考虑视力好的,也要考虑视力差的;要考虑喜欢看大字多翻页的,也要考虑看小字多显示内容的。所以当有一天我们的网页需要增加一个点击按钮切换大、正常、小甚至更多字号的时候,你就会意识到rem是多么的让你感动了。还是以上面的场景为例,我们假设通过在html标签上增加class来切换字体。
先看px的:
1 2 3 4 5 6 7 8 9 10 |
.article-title {font-size: 18px;font-weight: normal;} .article-body {font-size: 14px;margin: 10px 0;} .article-foot {font-size: 12px;} /* 大字号 */ html.big .article-title {font-size: 27px;} html.big .article-body {font-size: 21px;} html.big .article-foot {font-size: 18px;} /* 小字号 */ html.small .article-title {font-size: 14.4px;} ...此处省略几行 |
再看看使用rem的:
1 2 3 4 5 6 7 8 |
html {font-size: 10px;} .article-title {font-size: 1.8rem;font-weight: normal;} .article-body {font-size: 1.4rem;margin: 10px 0;} .article-foot {font-size: 1.2rem;} /* 大字号 */ html.big {font-size: 15px;} /* 小字号 */ html.small {font-size: 8px;} |
其优势,就不用我再多说了吧?
第二,在移动智能设备剧增,响应式网页设计如此火热的时代,我们在设计网页的时候,怎能不考虑移动设备,怎能不考虑移动设备高清屏?!通常移动设备的显示区域比起传统PC电脑已经少了很多很多,如何能在更小的区域显示更多的内容,一直是设备产商和开发者们努力的方向。高清屏的出现很大程度上解决了这个问题,有了高清屏就意味着在传统PC上的字号即便缩小一半,放到高清屏上仍然能够保证清晰可识别,不影响阅读,也不会导致信息丢失。所以,现在网页设计的时候通常会考虑在PC和Mobile中使用不同的字号等样式,那么问题来了,还是像第一个问题一样,在媒体查询中一个一个字号去覆盖吗?这显然是不科学的做法,虽然能达到我们想要的效果,但是成本是相当高的,而且费力不讨好。还是以上面的场景为例。
还是先看px的:
1 2 3 4 5 6 7 8 |
.article-title {font-size: 18px;font-weight: normal;} .article-body {font-size: 14px;margin: 10px 0;} .article-foot {font-size: 12px;} @media all and(max-width: 480px) { .article-title {font-size: 9px;} .article-body {font-size: 7px;} .article-foot {font-size: 6px;} } |
再看rem版本的:
1 2 3 4 5 6 7 |
html {font-size: 10px;} .article-title {font-size: 1.8rem;font-weight: normal;} .article-body {font-size: 1.4rem;margin: 10px 0;} .article-foot {font-size: 1.2rem;} @media all and(max-width: 480px) { html {font-size: 5px} } |
好了,不举其他的了,相信肯定还有更多的应用场景,但是这两个需求已经有足够的理由让我们去学习和尝试使用rem了。
好东西也有烦恼
至此,rem的优势不用再多说了,但是这么好的东西,我们在实际使用中却并非尽如人意:
这是在caniuse上截下来的rem的兼容性情况,看到左上角那块耀眼的红色了么?在国内IE覆盖还非常广泛的情况下,这块红色带给开发者的痛是痛彻心扉的,但是作为开发者,作为用户体验的服务方,我们很多情况下没理由去放弃他们,那么怎么解决rem的兼容性问题呢?
其实,也不难!CSS中不可被识别的属性或值会被浏览器自动忽略,所以,当我们在使用rem的时候,只要再增加一个px单位的尺寸,那么就可以解决IE8及以下版本浏览器的兼容性问题:
1 2 3 4 5 6 7 |
html {font-size: 10px;} .article-title {font-size: 18px;font-size: 1.8rem;font-weight: normal;} .article-body {font-size: 14px;font-size: 1.4rem;margin: 10px 0;} .article-foot {font-size: 12px;font-size: 1.2rem;} @media all and(max-width: 480px) { html {font-size: 5px} } |
总结
rem是一个非常有用的单位,在网页设计中常常可以带来事半功倍的效果,但是并不意味着rem可以替代所有的单位,有时候结合使用,相互配合,反而会达到意想不到的效果。然而,新东西的出现虽然总能让人耳目一新,但是却也常常会伴随着很多让人苦恼的坑,还需要我们慢慢去雕琢,慢慢去完善。