css
中的單位不少,%
、px
、em
、rem
,以及比較新的vw
、vh
等。每一個單位都有特定的用途,好比當須要設置一個矩形的寬高比爲16:9
,而且隨屏幕寬度自適應時,除了用%
,其餘單位是很難作到的。因此不存在說某個單位是錯誤的,某個單位是最好的這種說法。css
那本文說的頁面適配,指的是一樣的佈局,在不一樣大小的屏幕上怎麼進行縮放、控制間距、寬高、字號等大小。html
頁面適配的方式有不少:瀏覽器
px
,結合Media Query進行階梯式的適配;%
,按百分比自適應佈局;rem
,結合html
元素的font-size
來根據屏幕寬度適配;vw
、vh
,直接根據視口寬高適配。在這些大前提下,還需針對一些小的細節作微調。好比使用px
的時候,可能在小屏幕中,要對某個容器進行transform: scale(.8)
,適當縮小處理。使用rem
的時候,須要固定頁面的左右間距爲10px
等。函數
因此對我來講,儘管網上曾對px
、rem
和em
等單位的優缺點爭論過不少,但個人觀點多是,具體狀況具體分析。有同窗可能要炸了,你這跟沒說有啥區別?工具
對,個人意思跟開篇同樣,單論某個單位的好壞是沒意義的。咱們最關注的是:什麼場景中,使用什麼單位最合適。佈局
也不賣關子了,我就直接列一些本身以爲比較好的實踐方式,這些都是根據本身多年的開發經驗和大量的調研獲得的結論:字體
px
。好比1px
線,4px
的圓角邊框。rem
。em
。爲何我標題沒提到%
、vw
、vh
這幾個呢?這幾個都是按比例適配,只不過參考對象不同。spa
%
是參考父容器,vw
和vh
是參考視口。他們的使用場景是很是固定的,好比上文提到的16:9
的容器,除了用%
,還有更合適的方式嗎?另外,1vw = 1%的視口寬度
。因此就真正須要按視口大小適配的時候再用這個單位吧,使用場景相對固定。scala
接下來我會詳細介紹一下這3個結論的由來。設計
em
?em
會疊加計算。在這個機制下太容易犯錯了,由於你不知道這段css
指定的字號具體是多少。
// HTML <span> abc <span>def</span> abc </span> // CSS span {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
呢?
px
是我比較喜歡的一個單位,簡單又直接。但理性驅使,仍是要合理考慮使用場景。
px
的性質決定了它只能用於固定尺寸。也就是說,若是視覺設計師規定,這個邊框寬度必須是2px
。那這種狀況下就不須要討論了。
除了固定尺寸用px
,其餘大部分狀況均可以使用rem
。
如今考慮一個實際的開發場景,通常來講都是先有視覺稿才能開發。兩種狀況:1、假設視覺稿按iPhone 6和iPhone 6+,及其餘尺寸各出了一份,那你就按照Media Query去適配。2、設計師只給你一種機型的視覺稿,以iPhone 6爲例,750x1334
,2倍屏下轉換後是375x667
。
第一種狀況也不討論了,經過Media Query斷點適配後,其實你處理的仍是第二種狀況。
那第二種的意思是,你要根據寬度爲375px
的稿子,擴展到適配任意寬度的屏幕。(頁面高度跟業務有關,不用關心,寬度確定是固定的)
接下來拿到視覺稿以下:
測量後主要參數以下:
很快就能寫出HTML結構和CSS。
<div class="box box-1">A. 第一段內容</div> <div class="box box-2">B. 第二段內容</div>
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
吧。至於移動端,支持狀況不錯,能夠在生產環境使用。
因爲(大部分)瀏覽器的默認字號爲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
,用百分比換算後等於10px
,因此CSS
中的rem
是相對於10px
來計算,這樣計算的時候很方便,並且能夠相對於瀏覽器的設置來改變文字大小。
那爲何要用百分比呢?由於考慮到輔助功能和瀏覽器設置。對於部分用戶,可能會在手機或瀏覽器的設置中增大手機字號,這意味着對方平時看字是很費力的,因此他纔要放大。那把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,還不錯吧。
咱們來談最後一個話題。
當你知道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
的值。
本文沒有任何「PHP
是最好的語言」這種相似的導向,都是根據本身的經驗和觀察所得出的結論,如有不對請指正。
頁面適配是很精細的工做,可能你已經有了一套很是熟練的開發方式,那保持下去便可。若是沒有,不妨參考一下這篇文章。