前段時間試譯了Keith J.Grant的CSS好書《CSS in Depth》熏版,其中的第二章《Working with relative units》婴梧,書中對relative units的講解和舉例可以說相當(dāng)全面橙弱,看完之后發(fā)現(xiàn)自己并不太懂CSS相對單位,也希望分享給大家,所以有了這個譯文系列。(若有勘誤或翻譯建議奖唯,歡迎 Github PR ^_^
)
《別說你懂CSS相對單位》系列譯文:
- 如何更愉快地使用em
- 如何更愉快地使用rem [本文]
- 視口相關(guān)單位的應(yīng)用
- 無單位數(shù)字和行高
- CSS自定義屬性
本文對應(yīng)的章節(jié)目錄:
- 2.2 em和rem
- 2.2.2 對font-size使用rem
- 可用性:對font-size使用相對長度單位
- 2.2.2 對font-size使用rem
- 2.3 停止使用像素思維去思考
- 2.3.1 設(shè)置一個合理的字號默認(rèn)值
- 2.3.3 讓這個面板變得“響應(yīng)式”
- 2.3.3 調(diào)整單個組件的大小
2.2 em和rem
2.2.2 對font-size使用rem
當(dāng)瀏覽器解析HTML文檔時,創(chuàng)建了一個用來代表頁面元素的集合糜值,叫做DOM(文檔對象模型丰捷,Document Object Model)坯墨。樹狀結(jié)構(gòu),每一個節(jié)點(diǎn)代表一個元素病往。<html>
就是頂層節(jié)點(diǎn)(根節(jié)點(diǎn))捣染,在下面的是它的子節(jié)點(diǎn)<head>
和<body>
,再往下就是它們的子節(jié)點(diǎn)停巷,還有后代節(jié)點(diǎn)耍攘,如此類推。
根節(jié)點(diǎn)是文檔里所有其他元素的祖先叠穆。它有一個特別的偽類(pseudo-class)選擇器(:root)少漆,在樣式表里可以用這個選擇器表示臼膏。使用帶類名的類型選擇器html硼被,或者直接用標(biāo)簽選擇器,效果是一樣的渗磅。
rem是根em(root em)的縮寫嚷硫。rem是和根元素關(guān)聯(lián)的,不依賴當(dāng)前元素始鱼。不管你在文檔中的什么地方使用這個單位仔掸,1.2rem的計算值是相等的,等于1.2倍的根元素的字號大小医清。下面的示例代碼中起暮,聲明了根元素的字號大小,并在嵌套的無序列表中使用rem聲明字號大小会烙。
[ 代碼片段 2.10 使用rem聲明字號大小 ]
:root { 1
font-size: 1em; 2
}
ul {
font-size: .8rem;
}
- 1 偽類 :root 等價于 html 選擇器
- 2 使用瀏覽器的默認(rè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)字號大小,會有點(diǎn)不一樣掀亩。不僅僅是設(shè)置的入口比較難找(一般在瀏覽器的設(shè)置頁)舔哪,而且這個設(shè)置是永久的,直到用戶把默認(rèn)值還原槽棍。值得注意的是捉蚤,這個設(shè)置對使用px或其他絕對單位定義的字號大小無效。因為默認(rèn)字號大小對一些用戶是必要的炼七,尤其是弱視的群體缆巧,你應(yīng)該用相對單位或百分比來定義字號的大小。
rem簡化了很多em帶來的復(fù)雜度豌拙。事實上陕悬,rem提供了一個在px和em間的相對單位折中解決方案,而且更易于使用按傅。那么捉超,是不是意味著你應(yīng)該在對所有元素都使用rem,去掉其他長度單位呢唯绍?當(dāng)然不是拼岳。
在CSS的世界里,這個答案通常是况芒,看情況惜纸。rem只是你的工具箱中的其中一個。掌握CSS很重要的一點(diǎn)绝骚,就是學(xué)會分辨在什么場景下該使用什么工具耐版。我的選擇是,對font-size
使用rem皮壁,對border使用px椭更,對其他的度量方式如padding
、margin
蛾魄、border-radius
等使用em虑瀑。然而在必要時,需要聲明容器的寬度的話滴须,我更喜歡使用百分比舌狗。
這樣,字號大小就變得可預(yù)測扔水,而當(dāng)其他因素影響到元素的字號大小時痛侍,你也可以借助em去縮放元素的padding和margin。在border上使用像素是很合適的,尤其當(dāng)你想要一根漂亮的線的時候主届。以上就是我對不同屬性使用不同單位的理想方案赵哲,不過我要再次聲明,這些都是工具君丁,在某些特定場景下枫夺,利用不同的工具可能取到更好的效果。
提示
當(dāng)你不確定的時候绘闷,對
font-size
使用rem橡庞,對border
使用px,以及對其他大多數(shù)屬性使用em印蔗。
2.3 停止使用像素思維去思考
把頁面的根元素字號大小定義為0.625em或者62.5%扒最,在最近幾年來,這樣的用法很常見华嘹,這是一種模式吧趣,或者更貼切地說,這是一種反模式除呵。
[ 代碼片段 2.11 反模式:全局地把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實際等于多少像素它碎,并不重要函荣,你只需要知道這是比繼承的字號大一點(diǎn)點(diǎn),那就足夠了扳肛。而且傻挂,如果在屏幕上這不是你想要的效果,那就改吧挖息。這是需要時間實驗和試錯的金拒,但事實上,使用px的時候我們也需要這樣做套腹。(在第13章绪抛,我們會有更具體的方式來優(yōu)化這個實現(xiàn)方式。)
當(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í)慣橡类。在這章之后,我基本會使用相對單位來討論字號的大小芽唇。
2.3.1 設(shè)置一個合理的字號默認(rèn)值
先假設(shè)你想把默認(rèn)字號設(shè)定為14px顾画。把10px設(shè)定為基準(zhǔn)值,再在頁面中去覆蓋它的寫法匆笤,我們不推薦這種寫法研侣,相反,你應(yīng)該在根元素上直接聲明一個值炮捧。
在這個代碼片段里庶诡,目標(biāo)字號值是繼承的,瀏覽器的默認(rèn)值16px寓盗,那么14/16 = 0.875灌砖。
把下面的代碼添加到一個新的樣式表的最上面璧函,我們會在這上面添加其他代碼傀蚌。這里設(shè)定根元素(<html>
)的默認(rèn)字號大小。
[ 代碼片段 2.12 設(shè)定正確的默認(rèn)字號大小 ]
:root { 1
font-size: 0.875em; 2
}
- 1 或者使用 HTML 選擇器
- 2 14/16(期望值px / 繼承值px)等于0.875
現(xiàn)在蘸吓,你的期望基準(zhǔn)字號14px對整個頁面的元素有效善炫,你不需要在其他地方重新聲明了。你只需要在設(shè)計不一樣的地方修改成新的字號库继,譬如標(biāo)題箩艺。
我們一起來創(chuàng)建圖2.7那樣的面板吧!你創(chuàng)建的這個面板宪萄,基于14px字號艺谆,使用相對單位。
[ 圖 2.7 使用相對單位和繼承字號的面板 ]
下面是模板拜英,加到你的頁面吧静汤。
[ 代碼片段 2.13 面板的模板 ]
<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
藤抡。把下面代碼添加到你的樣式表吧。
[ 代碼片段 2.14 使用相對單位的面板 ]
.panel {
padding: 1em; 1
border-radius: 0.5em; 1
border: 1px solid #999; 2
}
.panel > h2 {
margin-top: 0; 3
font-size: 0.8rem; 4
font-weight: bold; 4
text-transform: uppercase; 4
}
- 1 對padding和border-radius使用em
- 2 用1px定義細(xì)邊框
- 3 把面板上面多余的空間去掉抹估,更多解釋看第3章
- 4 用rem控制標(biāo)題的字號大小
這段代碼給面板添加了一個細(xì)邊框以及定義了標(biāo)題的樣式缠黍。我希望標(biāo)題的字號小一點(diǎn),但要加粗和全是大寫药蜻。(你可以根據(jù)自己的設(shè)計瓷式,把字號改大點(diǎn)或者使用不同的排版方式)
第二個選擇器>
是一個直接后代組合選擇符(direct descendant combinator),它代表的是.panel
下的子元素h2
语泽。更完整的選擇器和組合選擇符的索引可以看附錄A蒿往。
在代碼片段2.13中,為了更清晰看到效果湿弦,我給body
添加了一個類panel-body
瓤漏,不過你會發(fā)現(xiàn),在你自己的代碼里是不需要的颊埃。因為這個元素從根元素上繼承了字號大小蔬充,它已經(jīng)是你想要看到的那樣。
2.3.3 讓這個面板變得“響應(yīng)式”
我們再更深入地看看這個問題班利。你可以根據(jù)屏幕尺寸的變化饥漫,添加媒體查詢來改變基礎(chǔ)字號大小,這可以令面板在不同尺寸的屏幕下罗标,有不同的大小變化庸队。(見圖2.8)
[ 圖 2.8 在不同屏幕大小的響應(yīng)式面板:300px(左上角),800px(右上角)闯割,1440px(下面) ]
媒體查詢(media query) —— 通過
@media
規(guī)則來聲明樣式彻消,在不同的屏幕尺寸或者媒體類型(如打印機(jī)或顯示器)下,觸發(fā)對應(yīng)的樣式控制宙拉。這是響應(yīng)式設(shè)計的關(guān)鍵要素宾尚。詳情看代碼片段2.15的這個例子,我在第8章會更深入的討論媒體查詢這個話題谢澈。
為了實現(xiàn)上面說的效果煌贴,把你的樣式代碼改成這樣。
[ 代碼片段 2.15 ]
:root { 1
font-size: 0.75em; 1
} 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)站的字號太小或者太大并思,你隨時可以做到通過修改一行代碼影響到全局的元素,這項改變會影響到頁面上的其他元素吕粗,不費(fèi)吹灰之力纺荧。
2.3.3 調(diào)整單個組件的大小
你也可以通過使用em縮放頁面上的一個獨(dú)立組件。有時颅筋,你可能會需要界面上的某些組件可以有個大號的版本。在我們的面板上這么做吧输枯,首先你需要給面板添加一個類名large
:<div class="panel large">
议泵。
在圖2.9,我們看到了面板的普通版和大號版的比較桃熄。效果類似響應(yīng)式面板先口,但是兩種尺寸是可以同時在同一個頁面中使用的型奥。
[ 圖 2.9 在一個頁面上的普通尺寸面板和大號面板 ]
我們來對面板的字號聲明方式做一些小的修改。你還是在使用相對單位碉京,但需要調(diào)整它們的基準(zhǔn)值厢汹。第一點(diǎn),給每個面板的父元素字號大小的定義font-size: 1rem
谐宙。這里指的是烫葬,不管在什么地方使用這個面板,每個面板的字號大小是一個確定值凡蜻。
第二點(diǎn)搭综,使用rem重新聲明標(biāo)題的字號大小,而不使用em划栓,這樣標(biāo)題就可以和剛才聲明的父元素字號1rem關(guān)聯(lián)起來兑巾。下面是對應(yīng)的代碼,更新下你的樣式表代碼吧忠荞。
[ 代碼片段 2.16 創(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代碼片段到你的樣式表头遭,定義一個大號面板吧寓免。
[ 代碼片段 2.17 利用一行代碼放大整個面板 ]
.panel.large { 1
font-size: 1.2rem;
}
- 1 組合選擇器指向同時有panel類和large類的元素
現(xiàn)在,你可以給普通面板添加class="panel"
和給大號面板添加class="panel large"
计维。類似地袜香,你也可以定義一個小號版本,只需要把父元素的字號設(shè)得比1rem小鲫惶。如果這個面板是一個更復(fù)雜的組件蜈首,包含多種字號大小或padding,也只需要一個聲明就可以重置大小欠母,只要所有的子元素都是使用em聲明的欢策。
《別說你懂CSS相對單位》系列譯文:
- 如何更愉快地使用em
- 如何更愉快地使用rem [本文]
- 視口相關(guān)單位的應(yīng)用
- 無單位數(shù)字和行高
- CSS自定義屬性
章節(jié):
- 2.1 相對單位值的魔力
- 2.1.1 完美像素設(shè)計(pixel-perfect design)的掙扎
- 2.1.2 完美像素網(wǎng)頁的終結(jié)
- 像素(pixel)、點(diǎn)(point)和pc(pica)
- 2.2 em和rem
- 2.2.1 對font-size使用em
- 當(dāng)我們在一個元素內(nèi)用em同時聲明font-size和其他屬性
- 字號收縮問題
- 2.2.2 對font-size使用rem
- 可用性:對font-size使用相對長度單位
- 2.2.1 對font-size使用em
- 2.3 停止使用像素思維去思考
- 2.3.1 設(shè)置一個合理的字號默認(rèn)值
- 2.3.2 讓這個面板變得“響應(yīng)式”
- 2.3.3 調(diào)整單個組件的大小
- 2.4 視口相關(guān)單位(viewport-relative units)
- CSS3
- 2.4.1 在font-size上使用vw
- 2.4.2 在font-size上使用calc()
- 2.5 不帶單位的數(shù)字(unitless number)和行高(line-height)
- 2.6 自定義屬性(也叫“CSS變量”)
- 2.6.1 動態(tài)改變自定義屬性的值
- 2.6.2 通過JavaScript改變自定義屬性的值
- 2.6.3 初探自定義屬性
- 總結(jié)
原著版權(quán)信息:
作者:Keith J.Grant
書籍:CSS in Depth
章節(jié):Working with relative units
筆者 @Yuying Wu赏淌,前端愛好者 / 鼓勵師 / 新西蘭打工度假 / 鏟屎官踩寇。目前就職于某大型電商的B2B前端團(tuán)隊。
感謝你讀到這里六水,對上文若有任何疑問或建議俺孙,歡迎留言辣卒。
如果你和我一樣喜歡前端,喜歡搗騰獨(dú)立博客或者前沿技術(shù)睛榄,或者有什么職業(yè)疑問荣茫,歡迎關(guān)注我以及各種交流哈。
獨(dú)立博客:wuyuying.com
知乎ID:@Yuying Wu
Github:Yuying Wu