YeaseonZhang

CSS单位全解

对于css单位的认识

对于网页布局的单位,只知道px是仅仅不够的,还需要知道其他几个比较常见的单位,特别是css3推出的一些新的度量单位。

em

em是一种相对单位,它相对于父元素的字体大小。

em常用于存在缩放需求时使用,比如在多行文本段落中,如果行高设置为line-height: 18px,如果文字的大小因为缩放发生改变,行高值是不会随之改变的,一直都是18px,如果将行高设置成一种相对值line-height: 1.2em,那么此时的行高值就会随着字体的大小改变而变化。

因为em是相对于父元素的字体大小,所以该单位存在明显的嵌套层级关系,浏览器默认的字体大小是16px,因此1em = 16px,需要注意的是chrome浏览器能够显示的最小字体是12px,当字体大小设置小于12px字体将按照12px显示。

See the Pen em by YeaseonZhang (@YeaseonZhang) on CodePen.

rem

rem(root em)是一种相对单位,和em不同点是rem相对于根元素html的字体大小。

利用这个特性,我们常常使用rem单位进行移动端页面的布局。

rem布局的本质是等比缩放,一般是基于宽度。

兼容性 iOS Android
rem 4.1+ 2.1+

See the Pen rem by YeaseonZhang (@YeaseonZhang) on CodePen.

现在移动端设计稿的尺寸大多为以iPhone6为基准的750px,首先将页面划分为100份,每一份的宽度为npx, 设置1rem = 10n,所以以750px为基准的话,每份就是7.5px1rem就对应75px。但这仅仅只能适配宽度为750px的设备,所以通过加载页面时动态计算设备的尺寸来,修改htmlfont-size值,就能实现页面缩放适配。

最简单设置rem基准值的方法。

1
2
3
4
document.addEventListener('DOMContentLoaded', function (e) {
var rem = window.innerWidth / 10 + 'px';
document.getElementsByTagName('html')[0].style.fontSize = rem;
})

使用scsspx转换为rem

1
2
3
4
@function px2rem ($px) {
$rem: 75px;
@return ($px / $rem) + rem;
}

也有人建议将设计稿宽度划分成100份,每一份就是一个rem单位,那么750px宽度的设计稿,对应的htmlfont-size = 1rem = 7.5px,方便兼容vh/vw单位。但是不建议这么做,你知道什么吗?

vh/vw

vh/vw单位类似于百分比单位不同之处在于vh/vw单位的布局不依赖于父级的宽高,而是相对于视口的宽高。
1vh等于1%的视口高度,1vw等于1%的视口宽度。若视口宽度是750px,那么1vw就是7.5px

目前移动端高端机型对于视口单位基本全面支持。

兼容性 iOS Android
vw 6.1+ 4.4+

See the Pen v-unit by YeaseonZhang (@YeaseonZhang) on CodePen.

:不同浏览器在获取视口的方法不同
IE9+、Firefox、Safari、Opera和Chrome均提供了4个属性innerWidthinnerHeightouterWidthouterHeight

  • IE9+、Safari和Firefox中,outerWidthouterHeight返回浏览器窗口本身的尺寸,而innerWidthinnerHeight则表示该容器中页面视图区的大小(减去边框宽度)
  • Chrome中,inner*outer*返回相同的值,即视口大小而非浏览器窗口的大小。
  • 在IE、Firefox、Safari、Opera和Chrome中,都能通过document.documentElement.clientWidthdocument.documentElement.clientHeight中保存了页面视口信息。

获取页面视口大小

1
2
3
4
5
6
7
8
9
10
11
12
var pageWidth = window.innerWidth,
pageHeight = window.innerHeight;

if (typeof pageWidth != 'number') {
if (document.compatMode == 'CSS1Compat') { // 浏览器标准模式
pageWidth = document.documentElement.clientWidth;
pageHeight = document.documentElement.clientHeight;
} else { // IE6 混杂模式
pageWidth = document.body.clientWidth;
pageHeight = document.doby.clientHeight;
}
}

其实,vw还可以和rem方案结合,这样就不需要js计算来设置html字体大小。

1
2
3
4
5
6
html {
font-size: 1vw
}
p {
width: 15rem;
}

往往一份设计稿为了兼容大屏设备,我们会采取限制布局的最大宽度。大于这个宽度的话页面居中并且,两边会留白。这个时候vw单位就无法满足我们的需求了。

vmin/vmax

vmin是指vhvw中较小的那一个的大小,当然vmax就是vhvw中较大的那一个。

例如,浏览器视口宽1100px、高700px,那么1vmin = 7px; 1vmax = 11px;如果浏览器视口宽800px,高1080px,那么1vmin = 8px; 1vmax = 10.8px

很有意思的是,使用这个单位的时候我们并不关心宽高,而是按照大小来区分,所以在移动端中的应用会比较多。

1
2
3
4
.box {
height: 100vmin;
width: 100vmin;
}
1
2
3
4
.box {
height: 100vmax;
width: 100vmax;
}

ch 和 ex

chex单位都是基于当前字体的特定单位。

ch单位,被定义为当前字体0字符的宽度。所以如果你使用的是等宽字体,那么你就可以直接定义一个盒子能够容纳多少个字符。

See the Pen ch by YeaseonZhang (@YeaseonZhang) on CodePen.

ex单位,被定义为当前字体x字符高度。这个单位通常用于排版微调,确保精确控制。

See the Pen ex by YeaseonZhang (@YeaseonZhang) on CodePen.

小结

  • em单位,还是老老实实作为字体/行高单位,如果用做布局使用,会牵一发而动全身,一个节点变化导致后代元素都需要重新计算

  • rem单位,需要结合js脚本动态设置html字体大小,如果用户禁用了js(少数情况),这种时候我们可以选择<noscript>开启JavaScript,获得更高的用户体验</noscript>;第二个方案就是使用媒体查询,为主流尺寸的设备设置html字体大小

  • vh/vw/vmin/vmax单位,对于设备系统浏览器要求比较高,如果不考虑兼容低版本浏览器,可以选择使用。当你选择使用vw/vh单位的时候,配合calc计算属性会更精确完成布局,例如width: calc(50vw - 40px)

  • ch/ex单位,使用的频率不高。如果使用的是等宽字体,ch单位可以用来布局,但是中文字体和英文字体等宽肯定是不一样宽的,所以还是不要考虑用来布局了。ex单位的应用场景,基本上使用em单位都能完成,所以也是一个可用可不用的单位。

参考资料