這篇文章給大家介紹的文章內容是關於css中單位的使用:選擇px還是rem,有很好的參考價值,希望可以協助到有需要的朋友。
css
中的單位很多,%
、px
、em
、rem
,以及比較新的vw
、vh
等。每個單位都有特定的用途,比如當需要設定一個矩形的寬高比為16:9
,並且隨螢幕寬度自適應時,除了用%
,其他單位是很難做到的。所以不存在說某個單位是錯誤的,某個單位是最好的這種說法。
那本文說的頁面適配,指的是同樣的布局,在不同大小的螢幕上怎麼進行縮放、控制間距、寬高、字型大小等大小。
頁面適配的方式有很多:
在這些大前提下,還需針對一些小的細節做微調。比如使用px
的時候,可能在小螢幕中,要對某個容器進行transform: scale(.8)
,適當縮小處理。使用rem
的時候,需要固定式頁面面的左右間距為10px
等。
所以對我來說,儘管網上曾對px
、rem
和em
等單位的優缺點爭論過很多,但我的觀點可能是,具體情況具體分析。有同學可能要炸了,你這跟沒說有啥區別?
對,我的意思跟開篇一樣,單論某個單位的好壞是沒意義的。我們最關注的是:什麼情境中,使用什麼單位最合適。
也不賣關子了,我就直接列一些自己覺得比較好的實踐方式,這些都是根據自己多年的開發經驗和大量的調研得到的結論:
在視覺稿要求固定尺寸的元素上使用px
。比如1px
線,4px
的圓角邊框。
在字型大小、(大多數)間距上使用rem
。
慎用em
。
為什麼我標題沒提到%
、vw
、vh
這幾個呢?這幾個都是按比例適配,只不過參考對象不一樣。
%
是參考父容器,vw
和vh
是參考視口。他們的使用情境是非常固定的,比如上文提到的16:9
的容器,除了用%
,還有更合適的方式嗎?另外,1vw = 1%的視口寬度
。所以就真正需要按視口大小適配的時候再用這個單位吧,使用情境相對固定。
接下來我會詳細介紹一下這3個結論的由來。
為什麼慎用em
?
em
會疊加計算。在這個機制下太容易犯錯了,因為你不知道這段css
指定的字型大小具體是多少。
// HTML<span> abc <span>def</span> abc</span>// CSSspan {font-size: 1.5em;}
實際的效果是這樣的:
先要搞清楚em
的計算原理,它是根據當前元素的字型大小按比例計算的。
外層span
的字型大小是16px
(瀏覽器預設值),所以1.5em
之後是24px
。由於字型大小是繼承的,導致內層span
的字型大小繼承過來是24px
,再經過1.5em
之後就成了36px
。
所以,就算要用em
的話,盡量不要用在繼承屬性(font-size
)上,除非你真的清楚你在做什麼!
比如你想根據字型大小自動調整字元間距,可以這麼做:
.content { font-size: 1rem; letter-spacing: .03em;}
但再仔細想一下,letter-spacing
由.content
的字型大小決定,而它又由html
的字型大小決定。那為什麼letter-spacing
不直接用rem
呢?
rem vs. px
px
是我比較喜歡的一個單位,簡單又直接。但理性驅使,還是要合理考慮使用情境。
px
的性質決定了它只能用於固定尺寸。也就是說,如果視覺設計師規定,這個邊框寬度必須是2px
。那這種情況下就不需要討論了。
除了固定尺寸用px
,其他大部分情況都可以使用rem
。
現在考慮一個實際的開發情境,一般來說都是先有視覺稿才能開發。兩種情況:一、假設視覺稿按iPhone 6和iPhone 6+,及其他尺寸各出了一份,那你就按照Media Query去適配。二、設計師只給你一種機型的視覺稿,以iPhone 6為例,750x1334
,2倍屏下轉換後是375x667
。
第一種情況也不討論了,通過Media Query斷點適配後,其實你處理的還是第二種情況。
那第二種的意思是,你要根據寬度為375px
的稿子,擴充到適配任意寬度的螢幕。(頁面高度跟業務有關,不用關心,寬度肯定是固定的)
接下來拿到視覺稿如下:
測量後主要參數如下:
頁面間距10px
文字間距10px,字型大小16px
A高度100px
B高度50px,上間距30px
很快就能寫出HTML結構和CSS。
<p class="box box-1">A. 第一段內容</p><p class="box box-2">B. 第二段內容</p>
body { padding: 10px; background: #f6f0ee;}.box { padding: 10px; font-size: 16px; color: #fff; box-sizing: border-box;}.box-1 { height: 100px; background: #1daedc;}.box-2 { margin-top: 30px; height: 50px; background: #ddbe97;}
完美符合要求。
然後視覺開始提要求了,大屏上要把字型放大、間距放大。
這時候的一個選擇是,問設計師是要適配哪種螢幕,字型大小是多少,間距是多少。技術上再通過Media Query微調。
@media(min-width: 414px) { // 這裡不寫了,按視覺要求量化即可}
另一個選擇可以反過來做。首先按rem作為字型大小、容器高度、外間距的單位。那麼代碼可以改為:
html { font-size: 16px;}.box { font-size: 1rem;}.box-1 { height: 6.25rem;}.box-2 { margin-top: 1.875rem; height: 3.125rem;}
其他的樣式規則不變,目前的結果和之前的是等價的。如果再加一點魔法,通過Media Query改變iPhone 6+的html
字型大小,其他元素的屬性就會自動變化。
@media(min-width: 414px) { html { font-size: 17.664px; }}
17.664 = 414 * 16 / 375
。
由此可以得到html
的font-size
計算公式為:fontSize = deviceWidth * 16 / 375
;
前提是你的html
有這條meta
屬性:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0,user-scalable=no">
至於為何是16px
,這個後面再介紹。所以rem
有個明顯的優點,它可以通過少量代碼解決大部分問題。
如果還存在某些細節不夠滿意,那再用Media Query微調。這種主觀的“好看”、“不好看”,可能註定沒法自動化解決吧。
關於rem相容性。案頭端的話僅在IE9+
支援。vw
和vh
一樣。所以如果要考慮IE8
的相容性,那沒別的選擇只能用px
吧。至於移動端,支援情況不錯,可以在生產環境使用。
html的font-size該如何設定
由於(大部分)瀏覽器的預設字型大小為16px
,所以一般來說把html
的font-size
歸一化為16px
是比較合適的實踐方式。同時可以參考這篇文章。
為了大家以後參考方便,我列了一些常用的Media Query斷點(以iPhone 6為基準)。
@media only screen and (min-width: 320px) { html { font-size: 13.65px; }}@media only screen and (min-width: 360px) { html { font-size: 15.36px; }}@media only screen and (min-width: 375px) { html { font-size: 16px; }}@media only screen and (min-width: 390px) { html { font-size: 16.64px; }}@media only screen and (min-width: 414px) { html { font-size: 17.664px; }}@media screen and (min-width: 640px) { html { font-size: 27.31px; }}
大家可能還會看到一些文章中建議把html
字型大小設成62.5%
。
html { font-size: 62.5%;}
因為剛提到瀏覽器預設的字型大小為16px
,因此換算成百分比就是62.5% = 1 / 16
。
那為什麼要用百分比呢?因為考慮到協助工具功能和瀏覽器設定。對於部分使用者,可能會在手機或瀏覽器的設定中增大手機字型大小,這意味著對方平時看字是很費力的,所以他才要放大。那把html的字型大小設定成百分比就很貼心了,會隨著手機設定改變頁面的字型大小。
在手機上設定預設字型大小是很常見的現象,所以如果是一個充滿人道主義的排版,我覺得用百分比是非常高尚的。它不僅從視覺角度去考慮美,更加做到了“使用者至上”這四個字。
好,回到現實環境。只有國外那些對Accessibility要求比較高的國家,才會真正去落實這些。但國內的話,老實說,更注重外觀的美。從來沒有哪家互連網公司的頁面會去相容Screen Reader,也很少做Keyboard Shortcut。
扯遠了,就算你看到用62.5%
的情況,有些間距也是不合理的,都做的不太好,特別是把文案做到圖片上的,對字型大小根本不敏感。如果出發點不是為了使用者的視覺接受能力,那就別用62.5%
;如果想做,就把縮放考慮到位了,別做半吊子。
另外,針對本小節開頭用16px
的情況,這裡再給大家提供一招(我調研了一下目前沒人這麼用,也是靈光一現才想到的)。
用Media Query的缺點是什嗎?它是分段函數,對於寬度在[320, 360)
區間內的螢幕,會適用同一套方案。最完美的應該是線性函數,怎麼做?很簡單,用vw
即可。
html { font-size: 4.266667vw;}
用1行代碼代替之前6個冗長的Media Query,還不錯吧。
如何提高rem的可讀性
我們來談最後一個話題。
當你知道html
的font-size
怎麼設定後,肯定想問,難道我每次寫代碼時,還得做個除法,把rem
的值計算出來嗎?
我相信稍微“現代”一點的開發人員,都會用到CSS預先處理。基於這個工具,事情就很好辦了,以LESS
為例,兩步操作如下:
// 1. 按iPhone 6的視覺稿,基準字型大小為16px,因此可以設定一個LESS變數。@px: 16rem;// 2. 通過LESS內建的除法自動運算。比如用到16px的字型大小時,寫成16/@px即可,最後會計算成1rem。.example { font-size: 16/@px; margin: 20/@px 0; padding: 20/@px 10/@px;}
本文給大家介紹了rem
的適配方式,如何設定html
的font-size
,如何更快地書寫rem
的值。