前言
一般而言,我們用CSS設(shè)置字體大小和元素長寬是這樣的:
.name {
? ? font-size: 16px;
? ? width: 100px;
}
(由于字體大小和元素長寬的原理一樣,下面統(tǒng)一討論字體抄邀。)
本來一切好好的龙致,但到了不同的屏幕上效果差別就很大了屠列。假設(shè)你的設(shè)計稿是按照iphone6的尺寸來標注岸啡,那在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汉柒,也許還要適配其他不同尺寸的屏幕误褪。而且如果每種適配都需要重新修改字體樣式的話,工作量就太大了碾褂。
當然兽间,最簡單的做法就是在head里面設(shè)置initial-scale,根據(jù)不同屏幕來決定縮放的值正塌。但是嘀略,這種做法有個不好的地方,就是它本身是一個放大功能传货,字體和圖片被放大之后會變模糊屎鳍,對于追求比較高的前端頁面來說可能難以接受。
還有另一個方面问裕,IE并不能縮放px字體的大小逮壁。如果在IE上進行了縮放,那字體還是那么大粮宛。
三種不同的單位
接下來介紹三種不同的長度單位(CSS Units)窥淆。
px
px,就是pixels巍杈。翻譯為像素并不十分精確忧饭,可能翻譯為點更好,但是已經(jīng)有另一個單位pt(points)筷畦,所以词裤,也只能繼續(xù)翻譯為像素了刺洒。這里的px不同于一般的像素,它的特性就是在不同的設(shè)備上代表的大小不同吼砂。在低清屏上逆航,1px就代表1像素,而在高清屏上渔肩,比如iphone 6上則代表2個像素因俐,而在iphone6 plus上則代表3個像素,因為6p是3倍的高清屏周偎。所以抹剩,當設(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的兼容性有勾,也是相當不錯的疹启。
利弊
使用px的話,基本上頁面元素的字體大小都是固定的蔼卡,甚至修改起來也很麻煩。而用em就能解決適配的問題挣磨,但壞處是每個大小都是相對父元素的雇逞,一旦某個節(jié)點有所變動,很容易造成其他節(jié)點也要變動茁裙,而且本身不是特別直觀塘砸,單看某個節(jié)點是1em并不能得到它的具體大小。而rem基本是最優(yōu)方案了晤锥,既可以很好地適配掉蔬,也可以直觀地修改。
下面會介紹將rem方案應(yīng)用到項目里的方法矾瘾。
REM方案
用px寫CSS女轿,構(gòu)建時替換為rem
并不提倡直接在代碼里寫rem,因為你并不知道你當前的1rem代表多少壕翩。所以最好的方式是代碼里直接用px描述字體和大小蛉迹,并在后期將其轉(zhuǎn)化為rem。
適配不同屏幕的方案
針對6和6p這些不同的屏幕放妈,我們可以使用media query來定義root element的字體大小北救,這樣就能輕松做到根據(jù)不同屏幕展現(xiàn)同樣的視覺效果。
構(gòu)建方案
構(gòu)建方案很簡單芜抒,分為兩步珍策,一個針對.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提供了不同的參數(shù)設(shè)置來轉(zhuǎn)化css中的px唉堪。比如rootValue用來定義轉(zhuǎn)化時根元素的值模聋,mediaQuery決定是否轉(zhuǎn)換media query中的大小,minPixelValue用來定義最小的不需轉(zhuǎn)化的px值(比如可以不轉(zhuǎn)化1px的大羞胙恰)链方。如果想要特制某些元素的大小不被轉(zhuǎn)化,可以通過8PX這樣的大寫方式來解決灶搜,因為pxtorem不會轉(zhuǎn)化這部分css祟蚀,而瀏覽器卻能夠識別工窍。此外還有白名單、黑名單前酿、小數(shù)點位數(shù)患雏、是否替換原來的px等參數(shù)可供設(shè)置。
處理html中的css
這部分比較有意思罢维。微信提供了posthtml-px2rem的方案來解決inline-style的問題淹仑,但不處理html中的style標簽,因為他們已經(jīng)把css獨立出去解決肺孵。但是匀借,不少框架還會在文件中使用style標簽,如果只需要處理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標簽的字體大小敲董,不讓其轉(zhuǎn)換紫皇,這樣會更顯得直觀一點。