談一談rem的應(yīng)用場景及其如何使用

rem

rem是什么

相信大多數(shù)同學(xué)都寫過移動端枕稀,那么對rem就很熟悉了命浴,它是相對長度單位琢唾。相對于根元素(即html元素)font-size計算值的倍數(shù)的一個css單位楞件,也就是我們
前端常說的適配單位rem兴蒸。


認(rèn)識rem

當(dāng)瀏覽器解析HTML文檔時视粮,創(chuàng)建了一個用來代表頁面元素的集合,叫做DOM(文檔對象模型橙凳,Document Object Model)蕾殴。樹狀結(jié)構(gòu),每一個節(jié)點代表一個元素岛啸。<html>就是頂層節(jié)點(根節(jié)點)钓觉,在下面的是它的子節(jié)點<head>和<body>,再往下就是它們的子節(jié)點坚踩,還有后代節(jié)點荡灾,如此類推。

根節(jié)點是文檔里所有其他元素的祖先堕虹。它有一個特別的偽類(pseudo-class)選擇器(:root)卧晓,在樣式表里可以用這個選擇器表示。使用帶類名的類型選擇器html赴捞,或者直接用標(biāo)簽選擇器逼裆,效果是一樣的。

rem是根em(root em)的縮寫赦政。rem是和根元素關(guān)聯(lián)的胜宇,不依賴當(dāng)前元素。不管你在文檔中的什么地方使用這個單位恢着,1.2rem的計算值是相等的桐愉,等于1.2倍的根元素的字號大小。

這樣前后鋪墊相信童鞋們可以理解它掰派。


對font-size使用rem

:root{                       1
   font-size: 1em;           2
}
ul{
   font-size: 1rem;
}
  • 1 偽類:root等價于css的html選擇器从诲;
  • 2 使用了瀏覽器標(biāo)準(zhǔn)字號(16px);

在這個示例里靡羡,根字號大小是瀏覽器的默認(rèn)大小16px(根元素的1em等于瀏覽器的默認(rèn)字號大邢德濉)。無序列表的字號大小為0.8rem略步,計算結(jié)果是12.8px描扯。因為這只跟根元素相關(guān),盡管你在列表里嵌套了列表趟薄,嵌套子列表的字號仍然保持不變绽诚。

可用性:對font-size使用相對長度單位

一些瀏覽器會提供給用戶2種方式定制文字的大小:縮放和設(shè)置一個默認(rèn)的字號大小。通過按Ctrl+或者Ctrl-恩够,用戶可以對頁面進(jìn)行縮放卒落。這在視覺上會把整個頁面的文字或圖片(其實是所有元素)都放大或縮小了。在一些瀏覽器玫鸟,這個改變只針對當(dāng)前的標(biāo)簽頁且是臨時的导绷,不會影響到新開的標(biāo)簽頁犀勒。

設(shè)置默認(rèn)字號大小屎飘,會有點不一樣。不僅僅是設(shè)置的入口比較難找(一般在瀏覽器的設(shè)置頁)贾费,而且這個設(shè)置是永久的钦购,直到用戶把默認(rèn)值還原。值得注意的是褂萧,這個設(shè)置對使用px或其他絕對單位定義的字號大小無效押桃。因為默認(rèn)字號大小對一些用戶是必要的,尤其是弱視的群體导犹,你應(yīng)該用相對單位或百分比來定義字號的大小唱凯。

深度了解rem

rem簡化了很多em帶來的復(fù)雜度。事實上谎痢,rem提供了一個在px和em間的相對單位折中解決方案磕昼,而且更易于使用。那么节猿,是不是意味著你應(yīng)該在對所有元素都使用rem票从,去掉其他長度單位呢?當(dāng)然不是滨嘱。

在CSS的世界里峰鄙,這個答案通常是,看情況太雨。rem只是你的工具箱中的其中一個吟榴。掌握CSS很重要的一點,就是學(xué)會分辨在什么場景下該使用什么工具囊扳。我的選擇是吩翻,對font-size使用rem,對border使用px宪拥,對其他的度量方式如padding仿野、margin、border-radius等使用em她君。然而在必要時脚作,需要聲明容器的寬度的話,我更喜歡使用百分比。

這樣球涛,字號大小就變得可預(yù)測劣针,而當(dāng)其他因素影響到元素的字號大小時,你也可以借助em去縮放元素的padding和margin亿扁。在border上使用像素是很合適的捺典,尤其當(dāng)你想要一根漂亮的線的時候。以上就是我對不同屬性使用不同單位的理想方案从祝,不過我要再次聲明襟己,這些都是工具,在某些特定場景下牍陌,利用不同的工具可能取到更好的效果擎浴。
提示:在你不確定的時候字號給rem,border給px毒涧,其他單位值給em

請停止使用像素思維去思考

把頁面的根元素字號大小定義為0.625em或者62.5%贮预,在最近幾年來,這樣的用法很常見契讲,這是一種模式仿吞,或者更貼切地說,這是一種反模式捡偏。
[ 下面代碼全局定義font-size為10px ]

html{
    font-size: .625em;
}

我并不推薦這種用法唤冈。這個用法把瀏覽器默認(rèn)的字號大小16px縮小到10px。這樣做的好處是簡化了計算霹琼,如果設(shè)計師告訴你字號大小應(yīng)該是14px务傲,那你可以很輕易地計算出1.4rem,畢竟我們還是在使用相對單位枣申。

一開始售葡,這看起來很方便,但事實上這樣的實現(xiàn)方式有兩個問題忠藤。第一挟伙,強(qiáng)制你寫了很多重復(fù)的樣式代碼。10px對于大多數(shù)文本來說太小了模孩,你需要在整個頁面中尖阔,來來回回地覆蓋它。你會發(fā)現(xiàn)榨咐,自己把一段段落(<p>)的字號大小聲明為1.4rem介却,然后又把導(dǎo)航(<nav>)的鏈接字號大小聲明為1.4rem,樣式代碼中還有很多這樣的用法块茁。這樣引入了更高的錯誤風(fēng)險齿坷,當(dāng)你需要修改時發(fā)現(xiàn)代碼耦合程度比較高桂肌,同時也會讓樣式文件變大。

第二個問題是永淌,你這么做的時候崎场,其實你還是在用像素的思維在思考。雖然在代碼里寫的是1.4rem遂蛀,但是在你的腦子里谭跨,其實還是想的是14px,哈哈李滴,我以前一直這樣螃宙。在響應(yīng)式網(wǎng)頁開發(fā)中,我們應(yīng)該學(xué)會適應(yīng)那些“模糊”的值悬嗓。1.2em實際等于多少像素污呼,并不重要,你只需要知道這是比繼承的字號大一點點包竹,那就足夠了。而且籍凝,如果在屏幕上這不是你想要的效果周瞎,那就改吧。這是需要時間實驗和試錯的饵蒂,但事實上声诸,使用px的時候我們也需要這樣做。

當(dāng)使用em時退盯,我們很容易陷入糾結(jié)彼乌,這個值轉(zhuǎn)化成像素值會是多少呢?尤其對于字號大小渊迁。你一直在乘和除以em值慰照,這樣你很快就會瘋掉了。相反琉朽,我希望你可以接受一項挑戰(zhàn)毒租,嘗試培養(yǎng)先開始使用em的習(xí)慣。如果你習(xí)慣使用像素箱叁,那轉(zhuǎn)成em是需要一定時間和練習(xí)的墅垮,但相信我,這很值得耕漱。

這不是在說你再也不使用像素了算色。如果你跟一個設(shè)計師合作,你可能需要用更精確的像素值去溝通螟够,這沒問題的灾梦。在項目的開始,你需要聲明一個基礎(chǔ)的字號大小(通常是對標(biāo)題或者標(biāo)注的常用字號)斥废。使用絕對值去描述大小椒楣,往往會更加容易。

轉(zhuǎn)換成rem會有計算環(huán)節(jié)牡肉,那就讓計算器去忙吧(通常我會在Mac電腦上按cmd+空格捧灰,在Spotlight里計算)。首先在根元素上聲明根字號大小统锤,從那開始毛俏,使用像素應(yīng)該是例外的情況,而不是常態(tài)饲窿。

在這章內(nèi)容里煌寇,我還是會持續(xù)地聊起像素。這會有助于我解釋相對單位的工作原理逾雄,同時也能幫助你培養(yǎng)計算em值的習(xí)慣阀溶。在這章之后,我基本會使用相對單位來討論字號的大小鸦泳。

設(shè)置一個合理在字號大小

先假設(shè)你想把默認(rèn)字號設(shè)定為14px银锻。把10px設(shè)定為基準(zhǔn)值,再在頁面中去覆蓋它的寫法做鹰,我們不推薦這種寫法击纬,相反,你應(yīng)該在根元素上直接聲明一個值钾麸。
在這個代碼片段里更振,目標(biāo)字號值是繼承的,瀏覽器的默認(rèn)值16px饭尝,那么14/16 = 0.875肯腕。

把下面的代碼添加到一個新的樣式表的最上面,我們會在這上面添加其他代碼芋肠。這里設(shè)定根元素(<html>)的默認(rèn)字號大小乎芳。

:root:{                      1
     font-size:0.87em;       2
}
  • 1 或者使用 HTML 選擇器;
  • 2 14/16(期望值px / 繼承值px)等于0.875;

現(xiàn)在,你的期望基準(zhǔn)字號14px對整個頁面的元素有效帖池,你不需要在其他地方重新聲明了奈惑。你只需要在設(shè)計不一樣的地方修改成新的字號,譬如標(biāo)題睡汹。

創(chuàng)建的這個面板肴甸,基于14px字號,使用相對單位囚巴。

摸版

代碼實例

<div class="panel">
    <h2>Single-origin</h2>
    <div class="panel-body">
        We have built partnerships with small farms around the world to
        hand-select beans at the peak of season. We then carefully roast
        in <a href="/batch-size">small batches</a> to maximize their
        potential.  </div>
</div>

下一段代碼是樣式的原在。你會在padding和border-radius使用em友扰,標(biāo)題的字號使用rem,以及border使用px庶柿。把下面代碼添加到你的樣式表吧村怪。

.panel {                 
  padding: 1em;                    
  border-radius: 0.5em;            
  border: 1px solid #999;          
}
.panel > h2 {
  margin-top: 0;                   
  font-size: 0.8rem;               
  font-weight: bold;               
  text-transform: uppercase;       
}

這段代碼給面板添加了一個細(xì)邊框以及定義了標(biāo)題的樣式。我希望標(biāo)題的字號小一點浮庐,但要加粗和全是大寫甚负。(你可以根據(jù)自己的設(shè)計,把字號改大點或者使用不同的排版方式)

第二個選擇器>是一個直接后代組合選擇符(direct descendant combinator)审残,它代表的是.panel下的子元素h2梭域。更完整的選擇器和組合選擇符的索引可以看附錄A。

在代碼片段2.13中搅轿,為了更清晰看到效果病涨,我給body添加了一個類panel-body,不過你會發(fā)現(xiàn)璧坟,在你自己的代碼里是不需要的既穆。因為這個元素從根元素上繼承了字號大小,它已經(jīng)是你想要看到的那樣沸柔。

讓這個面板變成‘響應(yīng)式’

我們再更深入地看看這個問題循衰。你可以根據(jù)屏幕尺寸的變化,添加媒體查詢來改變基礎(chǔ)字號大小褐澎,這可以令面板在不同尺寸的屏幕下,有不同的大小變化伐蒋。

:root {                            1
  font-size: 0.75em;               1
}
@media (min-width: 800px) {        2
  :root {                          2
    font-size: 0.875em;            2
  }                                2
}                                  2
@media (min-width: 1200px) {       3
  :root {                          3
    font-size: 1em;                3
  }                                3
}
  • 1 針對所有屏幕工三,但是在更大的屏幕會被覆蓋
  • 2 針對比800px更寬的屏幕,覆蓋默認(rèn)樣式代碼
  • 3 針對比1200px更寬的屏幕先鱼,覆蓋以上兩套樣式代碼

第一套樣式規(guī)則俭正,聲明了小屏幕中的默認(rèn)字號大小,這是我們想要在較小的屏幕上看到的字號大小焙畔。然后使用媒體查詢掸读,把800px和1200px分別作為兩個分水嶺逐級增加字號的大小,覆蓋掉默認(rèn)的代碼宏多。

針對頁面的根元素使用這些字號大小儿惫,響應(yīng)式地重新定義em和rem對應(yīng)的值,從而達(dá)到響應(yīng)改變整個頁面的效果伸但。盡管你沒有直接對這個面板做任何的修改肾请,它現(xiàn)在是響應(yīng)式的。在小屏幕上更胖,譬如一臺手機(jī)铛铁,字號大小會被渲染成更小的(12px)隔显。然后,在更大的屏幕上饵逐,寬大于800px和大于1200px的括眠,組件的字號會分別放大到14px和16px。改變你的瀏覽器窗口倍权,看看組件是怎么變化的吧掷豺。

如果你在整個頁面中像這樣嚴(yán)格使用相對單位,整個頁面會隨著視窗大小放大和縮小账锹。這會是你的響應(yīng)式策略里很重要的一部分萌业。上面的2套媒體查詢聲明代碼,可以幫助你節(jié)省在頁面的其他部分使用媒體查詢的額外代碼奸柬。不過生年,如果你在元素中聲明的字號大小是以像素為單位的,那就不會產(chǎn)生任何效果了廓奕。

類似地抱婉,如果你的老板或者客戶覺得現(xiàn)在網(wǎng)站的字號太小或者太大,你隨時可以做到通過修改一行代碼影響到全局的元素桌粉,這項改變會影響到頁面上的其他元素蒸绩,不費吹灰之力。

調(diào)整單個組件的大小

你也可以通過使用em縮放頁面上的一個獨立組件铃肯。有時患亿,你可能會需要界面上的某些組件可以有個大號的版本。在我們的面板上這么做吧押逼,首先你需要給面板添加一個類名large:<div class="panel large">步藕。

在下圖中,我們看到了面板的普通版和大號版的比較挑格。效果類似響應(yīng)式面板咙冗,但是兩種尺寸是可以同時在同一個頁面中使用的。

響應(yīng)式

我們來對面板的字號聲明方式做一些小的修改漂彤。你還是在使用相對單位雾消,但需要調(diào)整它們的基準(zhǔn)值。第一點挫望,給每個面板的父元素字號大小的定義font-size: 1rem立润。這里指的是,不管在什么地方使用這個面板士骤,每個面板的字號大小是一個確定值范删。

第二點,使用em重新聲明標(biāo)題的字號大小拷肌,而不使用rem到旦,這樣標(biāo)題就可以和剛才聲明的父元素字號1rem關(guān)聯(lián)起來旨巷。下面是對應(yīng)的代碼,更新下你的樣式表代碼吧添忘。

[代碼片段創(chuàng)建一個面板的大號版本 ]

.panel {
  font-size: 1rem;               1
  padding: 1em;
  border: 1px solid #999;
  border-radius: 0.5em;
}
.panel > h2 {
  margin-top: 0;
  font-size: 0.8em;              2
  font-weight: bold;
  text-transform: uppercase;
}
  • 1 給組件聲明確定的字號大小
  • 2 其他元素的字號大小用em和父元素字號關(guān)聯(lián)

這些修改看起來并沒有影響面板的樣式采呐,但是現(xiàn)在你已經(jīng)準(zhǔn)備好了,做一個大號的面板只需要修改一小行代碼搁骑。你需要做的斧吐,就是把父元素字號大小改寫成1rem以外的一個值。因為其他元素的計算方式都依賴父元素的字號大小仲器,只要修改它煤率,整個面板的相關(guān)尺寸都會發(fā)生改變。添加下一個CSS代碼片段到你的樣式表乏冀,定義一個大號面板吧蝶糯。

[ 代碼片段 利用一行代碼放大整個面板 ]

.panel.large {               1
  font-size: 1.2rem;
}
  • 1 組合選擇器指向同時有panel類和large類的元素

現(xiàn)在,你可以給普通面板添加class=”panel”和給大號面板添加class=”panel large”辆沦。類似地昼捍,你也可以定義一個小號版本,只需要把父元素的字號設(shè)得比1rem小肢扯。如果這個面板是一個更復(fù)雜的組件妒茬,包含多種字號大小或padding,也只需要一個聲明就可以重置大小蔚晨,只要所有的子元素都是使用em聲明的乍钻。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市铭腕,隨后出現(xiàn)的幾起案子团赁,更是在濱河造成了極大的恐慌,老刑警劉巖谨履,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異熬丧,居然都是意外死亡笋粟,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進(jìn)店門析蝴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來害捕,“玉大人,你說我怎么就攤上這事闷畸〕⑴危” “怎么了?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵佑菩,是天一觀的道長盾沫。 經(jīng)常有香客問我裁赠,道長,這世上最難降的妖魔是什么赴精? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任佩捞,我火速辦了婚禮,結(jié)果婚禮上蕾哟,老公的妹妹穿的比我還像新娘一忱。我一直安慰自己,他們只是感情好谭确,可當(dāng)我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布帘营。 她就那樣靜靜地躺著,像睡著了一般逐哈。 火紅的嫁衣襯著肌膚如雪芬迄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天鞠眉,我揣著相機(jī)與錄音薯鼠,去河邊找鬼。 笑死械蹋,一個胖子當(dāng)著我的面吹牛出皇,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播哗戈,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼郊艘,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了唯咬?” 一聲冷哼從身側(cè)響起纱注,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤共郭,失蹤者是張志新(化名)和其女友劉穎山孔,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體郎仆,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡蜀涨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年瞎嬉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片厚柳。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡氧枣,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出别垮,到底是詐尸還是另有隱情便监,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布碳想,位于F島的核電站烧董,受9級特大地震影響毁靶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜解藻,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一老充、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧螟左,春花似錦啡浊、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至钳吟,卻和暖如春廷粒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背红且。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工坝茎, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人暇番。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓嗤放,卻偏偏與公主長得像,于是被迫代替她去往敵國和親壁酬。 傳聞我的和親對象是個殘疾皇子次酌,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,691評論 2 361

推薦閱讀更多精彩內(nèi)容