CSS的長度單位適配方案

前言

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

.name {

? ? font-size: 16px;

? ? width: 100px;

}

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

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


原始的做法

更好的設(shè)計是,在iphone6 plus上把iphone6的設(shè)計放大。

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

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

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


三種不同的單位

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

px

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

em

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

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

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

rem

Relative to font-size of the root element

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

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

再來看看rem的兼容性,也是相當(dāng)不錯的。

rem的兼容性

利弊

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

下面會介紹將rem方案應(yīng)用到項目里的方法。


REM方案

用px寫CSS,構(gòu)建時替換為rem

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

適配不同屏幕的方案

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


構(gòu)建方案

構(gòu)建方案很簡單,分為兩步,一個針對.css文件,另一個針對html,包括html中的style標(biāo)簽以及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提供了不同的參數(shù)設(shè)置來轉(zhuǎn)化css中的px。比如rootValue用來定義轉(zhuǎn)化時根元素的值,mediaQuery決定是否轉(zhuǎn)換media query中的大小,minPixelValue用來定義最小的不需轉(zhuǎn)化的px值(比如可以不轉(zhuǎn)化1px的大?。H绻胍刂颇承┰氐拇笮〔槐晦D(zhuǎn)化,可以通過8PX這樣的大寫方式來解決,因為pxtorem不會轉(zhuǎn)化這部分css,而瀏覽器卻能夠識別。此外還有白名單、黑名單、小數(shù)點位數(shù)、是否替換原來的px等參數(shù)可供設(shè)置。

處理html中的css

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

更通用一點的處理方式是gulp-posthtml、posthtml-postcss、postcss-pxtorem,流程基本就是處理html中的css中的px,這里會統(tǒng)一把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,參數(shù)option也是一樣的。


完結(jié)

我們在代碼中使用px并以統(tǒng)一的規(guī)范來實現(xiàn)界面,根據(jù)不同的屏幕定制不同的基礎(chǔ)字體大小,并在構(gòu)建時將px轉(zhuǎn)為rem讓其適配不同的屏幕。

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


參考

postcss-pxtorem

posthtml-px2rem

gulp-posthtml

posthtml-postcss

gulp-postcss

微信:REM 解決方案

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

web app變革之rem

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容