什麼是 rem
可能在你使用收音機或用其他音樂播放器之前,就已經聽過「R.E.M.」這個詞了。在這個樂團眼中,這個詞是「淺睡眠時眼球的快速轉動」的縮寫,而在 css 中,rem 代表著「以根元素為參照物的 em 單位」。他不會讓你拋棄你的宗教信仰也不會讓你相信那個遠在月球的人,但是它可以幫助你實現一個和諧、平穩的設計。
依據 W3C 規範中 1rem 的定義:
1rem 與等於根元素 font-size 的計算值。當明確規定根元素的 font-size 時,rem 單位會以該屬性的初始值作參考。
這意味著 1rem 等於 html 元素的字體大小(大部分瀏覽器根元素的字體大小為16px)
Rem 單位 vs Em 單位
使用 em 單位最主要的問題是他們與用戶元素相關聯。在這種情況下,這些元素可以相互嵌套並造成意想不到的結果。讓我們來思考下面一個例子,在根元素的文字大小為預設值16px 的情況下,我們想要所有列表的字體大小均為12px :
html { font-size: 100%; } ul { font-size: 0.75em; }
假如有一個列表是嵌套在另一個列表下,那麼內列表的字體大小將會是外列表字體大小的75%(也就是9px ),我們仍然可以透過幾行程式碼來解決這個問題:
ul ul { font-size: 1em; }
這樣就可以解決這個問題,然而我麼仍需要特別關注那些嵌套特別深的元素。
當使用 rem 單位後,事情就變得簡單了:
html { font-size: 100%; } ul { font-size: 0.75rem; }
當所有尺寸都以根元素的文字大小作為參照後,就不再需要為嵌套的元素單獨定義樣式了。
使用rem 單位定義文字大小
Jonathan Snook 是第一批使用rem 單位來定義文字大小的開發者,早在2011 年5 月,他就發表了題為《使用rem 來定義文字大小》 的文章。和大多數 CSS 開發者一樣,他必須去解決在 em 單位在複雜的佈局上的一系列問題。
在那時候,舊版的 IE 依然有很大的市場份額,而且他們不可以縮放由 px 來定義的文本。然而,就像我們之前看到的那樣,在使用 em 單位的情況下,很容易忘記元素之前的嵌套關係,並且得到一個意想不到的結果。
使用 rem 單位來定義文字的大小最大的問題在於這些值有點難以使用。讓我們來看一個例子,假設根元素的文字大小是16px,我們常用的文字大小轉換為rem 值如下:
10px = 0.625rem
12px = 0.75rem
14px = 0.855 (base)
18px = 1.125rem
20px = 1.25rem
24px = 1.5rem
30px = 1.875rem 。因此,Snook 使用一個叫 62.5 的方式來解決這個問題。然而這並不是一個創新,因為它早已在em 單位中運用了:
body { font-size:62.5%; } /* =10px */ h1 { font-size: 2.4em; } /* =24px */ p { font-size: 1.4em; } /* =14px */ li { font-size: 1.4em; } /* =14px? */
因為rem 單位與根元素相關聯,Snook 改進後的方案變為了:
html { font-size: 62.5%; } /* =10px */ body { font-size: 1.4rem; } /* =14px */ h1 { font-size: 2.4rem; } /* =24px */
有一點值得考慮的是有一些瀏覽器不支援rem 單位。因此上面的程式碼可以按照以下方式來改寫
html { font-size: 62.5%; } body { font-size: 14px; font-size: 1.4rem; } h1 { font-size: 24px; font-size: 2.4rem; }
儘管這個解決方案看起來是最好的解決方案,但還是有人不建議使用這種方式。 Harry Roberts 寫了一篇文章,裡面記錄了他在實際使用 rem 單位過程中的一些感受。從他的觀點來看,雖然62.5% 這種解決方案使得計算變得簡單(因為字體大小以px 為單位時的值正好是以rem 為單位的10 倍),但是他迫使開發者重寫他們網站中的所有文字大小。
Chris Coyier 在 CSS-Tricks 提出了第三種解決方案。他的解決方式充分利用了到目前為止我們遇到的三種單位。根元素的長度單位依舊採用 px ,模組用 rem 單位,模組內的元素使用 em 單位。這種方式可以很容易的操作根元素的大小、縮放模組,模組內內容的大小以模組自身文字大小來進行縮放。 Louis Lazaris 隨後在 CSS 中 em 單位的強大之處 提出了他的觀點。
在下面的例子中你可以看出Chris 的解決方案是怎麼運作的:
程式碼可以看SitePoint(@SitePoint點擊預覽) 在CodePen 寫的《在CSS 中使用em 和rem 單位的方式》點擊預覽。
正如你所看到的那樣,沒有利用新技術來解決這個問題。可能有些組合方式只是被開發者的想像所限制。
在媒體查詢中使用 rem 單位
在媒體查詢中利用 em 和 rem 單位,與「行的最佳長度」的概念密切向關,並能給用戶帶來流暢的閱讀體驗。在 2014 年 9 月,Smashing Magazine 在 web typography 發表了一篇名叫 尺寸那些事: 在 web 響應式設計中掌握文字大小與行寬度的平衡的文章。最有趣的是,文章給出了行的最佳寬度度,45 到 85 個字元(包括空格和標點符號),65 是最理想的行寬值。
粗略的估计一个字节大小就是 1rem,利用这个方法我们就可以用一种移动优先的方式控制内容的单行文本流:
.container { width: 100%; } @media (min-width: 85rem) { .container { width: 65rem; } }
然而在媒体查询中使用 em 和 rem 单位作为媒体查询的条件时有一个有意思的细节:1 rem,1em 还有浏览器默认文字大小这三值表示这同一个值。这样做的原因可以在媒体查询规范得到解释(特别强调):
询中相对单位都是以一个初始值作为基准,这就意味着这些单位永远不会基于声明的结果。例如:在 HTML 中,em 单位与用户浏览器或者用户偏好设置中设置的初始文字大小有关,而不是页面上的样式中定义的文字大小。
让我们看一个关于这个特性的一个小例子:
在 CodePen 上看一个关于媒体查询的 demo
首先,在我们的 HTML 文档中,有一个元素将会展现视口的宽度:
`Document width: <span></span>px`
接下来是两条媒体查询语句,一条是使用 rem 单位,另一条使用 em 单位(这里为了简便,使用了 Sass)
html { font-size: 62.5%; /* 62.5% of 16px = 10px */ @media (min-width: 20rem) { /* 20*16px = 320px */ background-color: lemonchiffon; font-size: 200%; /* 200% of 16px = 32px */ } @media (min-width: 30em) { /* 30*16px = 480px */ background-color: lightblue; font-size: 300%; /* 300% of 16px = 48px */(译:原文是48px) } }
最后,我们使用一点 jQuery 在页面上显示视口的宽度,并且在窗口缩放的时候更新这个值:
$('span').text($(window).width()); $(window).on('resize', function(e) { $('span').text($(window).width()); });
在开头,我们使用了 62.5% 这个方法来说明,修改根元素字体大小不会对媒体查询产生任何影响。当我们更改窗口的宽度时,我们可以看到在 320 px 时,第一条媒体查询开始起作用,到480px第二条媒体查询开始起作用。任何一条在媒体查询中对文字大小声明的改变都没有起作用。唯一一个可以改变媒体查询中宽度的是在浏览器里更改默认文字大小。
因为这个原因,在媒体查询语句中使用 em 单位还是 rem 单位已经不那么重要了。事实上,无论是Foundation v5还是最近刚发布的Bootstrap v4 alpha都在他们的媒体查询中使用了 em 单位。
使用 rem 单位来缩放文档
我们能发现的第三种使用 rem 单位的方式是去构建可缩放组件。使用 rem 来定义元素的宽度,外边距和内边距 通过使用根元素的字体大小作为一个接口使元素缩放一致变为了可能。 我们可以通过下面两个例子来看这是怎么起作用的。
使用 rem 来缩放文档实例一
在这个例子里,我们通过媒体查询中更改根元素的文字大小。就像上一个章节所讲,这样做的目的是为用户定制不同设备下的不同阅读体验。通过 rem 单位来表示宽度,外边距,内边距,这样所有元素就会基于用户的设备大小缩放。
让我们看另一个例子:
代码可以看 SitePoint(@SitePoint点击预览) 在 CodePen 写的 《使用 rem 动态缩放模块》点击预览
在第二个例子中,我们使用 JavaScript 来做同样的操作。这次用户根据自己的需要手动控制界面的大小。我们可以使用多种方式(可以使用数据库,cookie 还有本地存储)来存储用户数据,这样就可以给用户搭建一个基于用户偏好的个性化系统。
总结
在这里总结一下到目前为止我们对 CSS 中 rem 单位的认识。很显然,在项目中使用 rem 有许多优点,比如:响应式,可缩放,增加阅读体验,增加自定义元素的灵活性。rem 虽然不是一个通用的解决方案,但是通过谨慎的使用,它还是可以解决困扰开发者多年的问题。 我们每个人都可以去挖掘 rem 的所有潜能。从你的编辑器开始吧,实验并向我们分享您的成果。