前段時間試譯了Keith J.Grant的CSS好書《CSS in Depth》,其中的第二章《Working with relative units》,書中對relative units的講解和舉例可以說相當全面,看完之後發現自己並不太懂CSS相對單位,也希望分享給大家,所以有了這個譯文系列。(若有勘誤或翻譯建議,歡迎 Github PR ^_^)
《別說你懂CSS相對單位》系列譯文:
本文對應的章節目錄:
-
2.4 視口相關單位(viewport-relative units)
- CSS3
- 2.4.1 在font-size上使用vw
- 2.4.2 在font-size上使用calc()
2.4 視口相關單位(viewport-relative units)
你已經學完em和rem了,它們都是以font-size
為基準值的,但相對單位不只它們。還有視口相關單位,依賴瀏覽器的視口大小來定義長度的。
視口(viewport) —— 在瀏覽器視窗中用來渲染頁面的可視區域,這不包括瀏覽器的位址列、工具欄、狀態列等(如果有的話)。
如果你不熟悉視口相關單位的話,在這裡簡單介紹一下。
- vh —— 視口高度的1/100
- vw —— 視口寬度的1/100
- vmin —— 視區寬度或高度較小值的1/100(IE9支援的是vm)
- vmax —— 視區寬度或高度較大值的1/100(在寫本書時,IE或者Edge都不支援)
舉個例子,50vw等於視口寬度的一半,而25vh等於視口高度的25%。vmin依賴兩者(寬或高)的較小值,如果我們需要確保一個元素不管在橫屏還是豎屏下適應螢幕展示的話,這個屬性會很有幫助:如果是橫屏,vmin的基準值是螢幕的高度,如果是豎屏,它的基準值是螢幕的寬度。
圖2.10展示了一個正方形的元素在不同螢幕尺寸下的視口的情況。寬和高的值都宣告為90vmin,也就是寬高較小值的90%。邊長的值等於,橫屏情況下高度的90%,或者豎屏情況下寬度的90%。
[ 圖 2.10 如果把一個元素的寬高定義成90vmin,它總會展示成一個正方形,邊長稍小於螢幕的視口,不管它的尺寸或方向怎樣。 ]
在程式碼片段2.18可以看到這個元素的樣式,渲染了一個適應螢幕尺寸的大正方形,不管瀏覽器的尺寸是多少。你可以通過新增<div class="square">
,再看看頁面效果。
[ 程式碼片段 2.18 邊長使用vmin
的正方形元素 ]
.square {
width: 90vmin;
height: 90vmin;
background-color: #369;
}
如果想做一個大英雄圖片充滿螢幕的效果,視口相關長度最合適不過。你的圖片可以在一個長條形的容器內,把圖片的高度設為100vh,那它的高度就會跟視口高度一樣。
筆記
視口相關單位對於大多數瀏覽器還是一項比較新的特性,所以當你試圖把這個特性和其他樣式混搭時,有可能會有一些很奇怪的bug。詳情參考http://caniuse.com/#feat=viewport-units列表中的“已知問題(Known Issues)”
CSS3
本章提到的很多單位型別,其實並不在早期的CSS版本里(尤其是rem和視口相關單位)。在這門語言一系列的更新迭代過程中,它們慢慢被加進來,我們將最新的版本稱作CSS3。
在二十世紀末二十一世紀初,在CSS規範的初版釋出之後的很長一段時間,只有很小的改動。在1998年5月份,W3C(World Wide Web Consortium)釋出了CSS 2規範。不久之後,修正版本2中問題和缺陷的2.1版本開始了,CSS 2.1的工作持續了好多年,但並沒有新增什麼令人印象深刻的特性。直到2011年4月份,版本2.1終於被確認為“提議推薦標準”(Proposed Recommendation)。到這個時候,大多數瀏覽器對CSS 2.1的特性已經支援得很好了,在此基礎上,瀏覽器又努力地新增一些新的特性。這就是新規範CSS 3。
“3”是個非正式的版本號,實際上並沒有CSS3規範。相反,這個規範被拆成多個獨立的模組,分別有獨立的版本號。background和border的規範已經從盒模型(box model)以及層疊與繼承(cascading and inheritance)規範中獨立出來。通過這種方式,W3C就可以針對CSS某個模組進行更新迭代,而不用同時更新其他不相關的模組的內容。在這些模組規範裡,很多還停留在第3版本(現在叫“第3級”),但有的模組(比如選擇器規範(selectors specification))已經到第4級,而其他的模組(比如flexbox)還在第1級。
這些新特性進入了人們的視野。我們可以看到在2009到2013年間,大量新的CSS特性湧進瀏覽器中。其中有現在比較出名的rem和視口相關單位,以及新的選擇器(new selectors)、媒體查詢(media queries)、網頁文字(web fonts)、圓形邊框(rounded borders)、動畫(animation)、變換(transitions)、變形(transformations)以及定義顏色的不同方式。然而,每年的新特性的數量還在逐年穩定增長。
這意味著,我們不再只跟一個特定版本的CSS規範打交道。這是一套有生命的標準,每個瀏覽器也在持續地支援新的特性,開發者會開始使用然後漸漸習慣它們。CSS4大概不會出現了,如果有的話,應該也只是個用於市場營銷的名詞。儘管這本書也會提到CSS3的新特性,但沒有必要把它們都搬出來,就整個網頁而言,這些都是CSS。
2.4.1 在font-size上使用vw
一個應用如果使用了視口相關單位,可能效果最不明顯的地方就是用在字號大小上。事實上,我發現把vh和vw用在字號上比元素的寬或者高更實用。
試想一下,如果把元素的font-size宣告為2vm,會怎麼樣?桌上型電腦螢幕寬是1200px,2vm等於24px(1200 2%)。而平板電腦的螢幕寬768px,2vm約等於15px(768 2%)。很棒的是,元素在兩個尺寸下縮放自如。這意味著這裡並沒有一個突然的斷點,元素會隨著視口尺寸的增大而平滑增大。
不幸的是,24px對於大螢幕來說有點太大了。而更糟糕的是,在iPhone6它直接縮小到7.5px。好訊息是縮放生效了,而壞訊息是極限情況的處理有點差。你可以通過CSS的方法calc()
解決這個問題。
2.4.2 在font-size上使用calc()
calc()
函式支援對2個或者更多個數值進行基礎的運算。這個函式對不同型別的單位間的運算尤其有用。這個函式支援加(+)、減(-)、乘(*)和除以(/)。其中,加和減運算子左右必須留有空格,所以我建議我們來培養一個習慣,總是在四個運算子的兩側都寫上空格,譬如calc(1em + 10px)
。
你會在下一個程式碼片段中,使用calc()
來計算vh單位和em單位的值。把你的樣式表中的上一段設定基礎字號大小的程式碼去掉(及相關的媒體查詢程式碼),新增以下程式碼。
[ 程式碼片段 2.19 在font-size中使用em和vh單位進行calc()運算 ]
:root {
font-size: calc(0.5em + 1vw);
}
現在,開啟頁面,緩慢地改變瀏覽器的大小。你會發現,字號改變的過渡很平滑。0.5em在這裡代表的是字號的最小值,1vm則代表著響應式地往上累加。這樣基礎字號大小就在iPhone6的11.75px和1200px寬瀏覽器視窗的20px間縮放。你可以根據自己的喜好改變這些值。
你現在可以實現響應式策略的核心邏輯而不需要新增一行媒體查詢的程式碼。頁面上的所有元素可以根據視口大小平滑縮放,不再需要3或4個硬編碼的斷點。
(後一篇《無單位數字和行高》已同步釋出,瞭解一下 ^_^
)
《別說你懂CSS相對單位》系列譯文:
章節:
-
2.1 相對單位值的魔力
- 2.1.1 完美畫素設計(pixel-perfect design)的掙扎
- 2.1.2 完美畫素網頁的終結
- 畫素(pixel)、點(point)和pc(pica)
-
2.2 em和rem
-
2.2.1 對font-size使用em
- 當我們在一個元素內用em同時宣告font-size和其他屬性
- 字號收縮問題
-
2.2.2 對font-size使用rem
- 可用性:對font-size使用相對長度單位
-
-
2.3 停止使用畫素思維去思考
- 2.3.1 設定一個合理的字號預設值
- 2.3.2 讓這個皮膚變得“響應式”
- 2.3.3 調整單個元件的大小
-
2.4 視口相關單位(viewport-relative units)
- CSS3
- 2.4.1 在font-size上使用vw
- 2.4.2 在font-size上使用calc()
- 2.5 不帶單位的數字(unitless number)和行高(line-height)
-
2.6 自定義屬性(也叫“CSS變數”)
- 2.6.1 動態改變自定義屬性的值
- 2.6.2 通過JavaScript改變自定義屬性的值
- 2.6.3 初探自定義屬性
- 總結
原著版權資訊:
作者:Keith J.Grant
書籍:CSS in Depth
章節:Working with relative units
筆者 @Yuying Wu,前端愛好者 / 鼓勵師 / 紐西蘭打工度假 / 鏟屎官。目前就職於某大型電商的B2B前端團隊。
感謝你讀到這裡,對上文若有任何疑問或建議,歡迎留言。
如果你和我一樣喜歡前端,喜歡搗騰獨立部落格或者前沿技術,或者有什麼職業疑問,歡迎關注我以及各種交流哈。
獨立部落格:wuyuying.com
知乎ID:@Yuying Wu
Github:Yuying Wu