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)式面板咙冗,但是兩種尺寸是可以同時在同一個頁面中使用的。
我們來對面板的字號聲明方式做一些小的修改漂彤。你還是在使用相對單位雾消,但需要調(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聲明的乍钻。