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的大小)。如果想要特制某些元素的大小不被转化,可以通过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阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容