CSS的长度单位适配方案

作者: coltfoal | 来源:发表于2016-08-02 12:36 被阅读1791次

前言

一般而言,我们用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

相关文章

  • CSS的长度单位适配方案

    前言 一般而言,我们用CSS设置字体大小和元素长宽是这样的: .name { font-size: 16px; ...

  • 几个CSS的单位你需要了解一下

    css长度单位 css 长度单位一般我们分为绝对长度单位和相对长度单位 绝对长度单位 绝对长度单位是一个固定的值,...

  • CSS之长度单位

    CSS之长度单位 很多CSS属性要靠长度度量衡才能正确显示元素。因此,CSS中有许多长度单位。CSS中的长度单位分...

  • css 单位和值

    css 单位和值 一、绝对长度单位 常用的绝对长度单位: px pixel 是 CSS 中最常用的长度单位,可以用...

  • css长度单位

    CSS有两种类型的单位长度:相对和绝对。相对长度单位指定了一个长度相对于另一个长度的属性。对于不同的设备,相对长度...

  • CSS - 长度单位

    研究背景 一般用于描述 font-size、padding 或者 border 的长度都使用 px 单位。但最近看...

  • css长度单位

    字体相关相对长度单位 em、ex、ch、rem是字体相关的相对长度单位 em em表示元素的font-size属性...

  • CSS长度单位

    像素 px em 百分比 注意但当给 font-size 设置单位为 em 时,此时计算的标准以 p 的父元素的 ...

  • CSS长度单位

    前言 说到css的单位,大家应该首先想到的是像素单位px,我们在网页布局中一般都是用px,但是近年来自适应网页布局...

  • Css单位

    CSS 单位——来自菜鸟教程 CSS 有几个不同的单位用于表示长度。 一些设置 CSS 长度的属性有 width,...

网友评论

  • 0500860f8a39:学习了,楼主的方案很好,我提出一个小问题。
    楼主都有提到pt,那么为什么不使用pt呢?
    point,大约1/72英寸; (1pt = 1/72in)
    可以看出point跟我们的厘米毫米一样是绝对的单位。
    point估计也是纸质印刷所使用的标准单位呢。

    可以设置body和html的字体为pt单位(例如iPhone6设计稿上边是1pt = 2px)
    其他的元素的字体使用rem。

    不用px的理由是正如楼主所说,在不同设备上一个px的视觉长度并不相同。而pt则是绝对长度,也就是说视觉长度是一样的。
    0500860f8a39:@coltfoal 一直不理解楼主说的“pt和px一样”,查了一遍,才知道原来...
    CSS 的单位不是根据物理上的英寸来表现的,而是表现为 96px(译注:这里指的应该是 1in = 96px)。这意味着无论真实屏幕的像素密度是多少,(在 CSS 中)它都假设为 96dpi。在一个高像素密度的设备中,1in 会小于实际的 1 物理英寸。类似地 mm、cm 和 pt 都不是一个绝对的长度单位。
    coltfoal:pt和px一样,相对em和rem来说,都有一个缺点,就是一旦要修改大小,则需要全部代码都修改。
  • ea16fb7f061d:最后一句是是啥意思
    coltfoal:@summer323wy
    一般使用media query来设置html的基准字体,比如
    html {
    font-size: 24px;
    }
    但是一般不对这部分做转换,因为这样会比较直观一点,一看就知道基准字体是多少了。
  • blaver:受用

本文标题:CSS的长度单位适配方案

本文链接:https://www.haomeiwen.com/subject/owmfsttx.html