CSS的長度單位適配方案

前言

一般而言,我們用CSS設置字體大小和元素長寬是這樣的:

.name {

? ? font-size: 16px;

? ? width: 100px;

}

(由于字體大小和元素長寬的原理一樣,下面統一討論字體。)

本來一切好好的,但到了不同的屏幕上效果差別就很大了。假設你的設計稿是按照iphone6的尺寸來標注,那在iphone6 plus上,由于你的字體還是一樣大,所以在iphone6 plus上看起來會小一點。如果屏幕尺寸再大,則會再小,效果和UI設計的看起來就不太一樣了。特別是某些固定尺寸的元素,看起來就會很奇怪。


原始的做法

更好的設計是,在iphone6 plus上把iphone6的設計放大。

比如6的屏幕寬度是375,字體大小為16,而6p的寬度為414,那字體就應該是414/375*16=17.6px。也就是根據兩者之間的比例來放大字體。然而,屏幕并不只有6和6p,也許還要適配其他不同尺寸的屏幕。而且如果每種適配都需要重新修改字體樣式的話,工作量就太大了。

當然,最簡單的做法就是在head里面設置initial-scale,根據不同屏幕來決定縮放的值。但是,這種做法有個不好的地方,就是它本身是一個放大功能,字體和圖片被放大之后會變模糊,對于追求比較高的前端頁面來說可能難以接受。

還有另一個方面,IE并不能縮放px字體的大小。如果在IE上進行了縮放,那字體還是那么大。


三種不同的單位

接下來介紹三種不同的長度單位(CSS Units)。

px

px,就是pixels。翻譯為像素并不十分精確,可能翻譯為點更好,但是已經有另一個單位pt(points),所以,也只能繼續翻譯為像素了。這里的px不同于一般的像素,它的特性就是在不同的設備上代表的大小不同。在低清屏上,1px就代表1像素,而在高清屏上,比如iphone 6上則代表2個像素,而在iphone6 plus上則代表3個像素,因為6p是3倍的高清屏。所以,當設計稿給出iphone 6的尺寸時,你必須把它除以2,寫成px,才能在移動設備上正確地顯示尺寸。

em

Relative to the font-size of the element (2em means 2 times the size of the current font)

意思就是,某個元素的字體大小與它的父元素的相對單位。

這個很好理解,比如父元素A,擁有子元素B。假設A字體設置為1em,B設置為2em,而1em=16px,那最后A的字體是16px,B的字體是32px。而B又擁有子元素C,C設置為0.5em,則C的字體為32px*0.5=16px。這里的32px是B元素的字體大小。

rem

Relative to font-size of the root element

和em類似,不同的是,rem相對的是根元素的字體大小。

假設html的字體為16px,擁有A元素,字體為2rem,那A的字體就是32px。假設A擁有B,而B為2rem,那B的字體也為32px,因為它相對的是html,而不是A。假設B的字體為2em,那B就是64px了。

再來看看rem的兼容性,也是相當不錯的。

rem的兼容性

利弊

使用px的話,基本上頁面元素的字體大小都是固定的,甚至修改起來也很麻煩。而用em就能解決適配的問題,但壞處是每個大小都是相對父元素的,一旦某個節點有所變動,很容易造成其他節點也要變動,而且本身不是特別直觀,單看某個節點是1em并不能得到它的具體大小。而rem基本是最優方案了,既可以很好地適配,也可以直觀地修改。

下面會介紹將rem方案應用到項目里的方法。


REM方案

用px寫CSS,構建時替換為rem

并不提倡直接在代碼里寫rem,因為你并不知道你當前的1rem代表多少。所以最好的方式是代碼里直接用px描述字體和大小,并在后期將其轉化為rem。

適配不同屏幕的方案

針對6和6p這些不同的屏幕,我們可以使用media query來定義root element的字體大小,這樣就能輕松做到根據不同屏幕展現同樣的視覺效果。


構建方案

構建方案很簡單,分為兩步,一個針對.css文件,另一個針對html,包括html中的style標簽以及html中的inline-style。

處理普通的css文件

目前比較好用的處理css文件的插件是gulp-postcss和postcss-pxtorem配合使用,比如像這樣:

var postcss = require('gulp-postcss');

var pxtorem = require('postcss-pxtorem');

? ? var options = {

? ? rootValue: 10,

? ? propWhiteList: [],

? ? minPixelValue: 1};

gulp.src('www/*.css').pipe(postcss([pxtorem(options)])).pipe(gulp.dest('build/'));

postcss-pxtorem提供了不同的參數設置來轉化css中的px。比如rootValue用來定義轉化時根元素的值,mediaQuery決定是否轉換media query中的大小,minPixelValue用來定義最小的不需轉化的px值(比如可以不轉化1px的大?。H绻胍刂颇承┰氐拇笮〔槐晦D化,可以通過8PX這樣的大寫方式來解決,因為pxtorem不會轉化這部分css,而瀏覽器卻能夠識別。此外還有白名單、黑名單、小數點位數、是否替換原來的px等參數可供設置。

處理html中的css

這部分比較有意思。微信提供了posthtml-px2rem的方案來解決inline-style的問題,但不處理html中的style標簽,因為他們已經把css獨立出去解決。但是,不少框架還會在文件中使用style標簽,如果只需要處理inline-style的話也可以用這個方案。

更通用一點的處理方式是gulp-posthtml、posthtml-postcss、postcss-pxtorem,流程基本就是處理html中的css中的px,這里會統一把inline-style一起解決,所以是個不錯的選擇。

var posthtml = require('gulp-posthtml');

var posthtmlcss = require('posthtml-postcss');

var pxtorem = require('postcss-pxtorem');

var options = {};

gulp.src('www/*.html').pipe(posthtml([posthtmlcss([pxtorem(options)])])).pipe(gulp.dest('build/'));

這里使用了和上面同樣的postcss-pxtorem,參數option也是一樣的。


完結

我們在代碼中使用px并以統一的規范來實現界面,根據不同的屏幕定制不同的基礎字體大小,并在構建時將px轉為rem讓其適配不同的屏幕。

其實一般我們都需要額外定制html標簽的字體大小,不讓其轉換,這樣會更顯得直觀一點。


參考

postcss-pxtorem

posthtml-px2rem

gulp-posthtml

posthtml-postcss

gulp-postcss

微信:REM 解決方案

css3的字體大小單位[rem]到底好在哪?

web app變革之rem

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,739評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,634評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,653評論 0 377
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,063評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,835評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,235評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,315評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,459評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,000評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,819評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,004評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,560評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,257評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,676評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,937評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,717評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,003評論 2 374

推薦閱讀更多精彩內容