px

在平时的工作当中,我发现自己大多数时候是用px来作为CSS字体单位的,不仅如此,其实公司的所有前端项目都是以px作为CSS字体单位的。我们知道px(像素)作为CSS相对长度单位是相对于显示器的分辨率而言的。它的特点是稳定、精确、浏览器兼容性好,但是对应的,在Web页面中使用px作为字体的单位时也有它的问题,比如当用户试图调整浏览器的默认字体大小时,由于px是固定大小的,所以再怎么调整对应页面上字体的大小都是不会变的。

em

于是为了解决上面提到的px作为字体单位的类似问题,又引入了一个新的CSS字体单位em,em作为字体单位也是一个相对长度单位,它相对于当前对象内文本的字体大小,若当前对象内文本的字体大小未被设置,则采用浏览器默认的字体大小。

任意浏览器的默认字体大小都是16px,所以在浏览器字体大小保持默认的状态下:1em = 16px,那么1px = 1 / 16 = 0.0625em,10px = 0.625em,同理12px = 0.0625 x 12 = 0.75em,14px = 0.0625 x 14 = 0.875em。

但是如果每次都要去进行对应的px值到em值得计算的话,想必会大大降低开发效率,为了简化px到em的值转换,可以在CSS中声明body的字体大小为62.5%,即body {font-size: 62.5%},这样一来,1em = 16px * 62.5% = 10px,那么对应的12px = 1.2em,14px = 1.4em,这样换算起来就简单的多了。

但是像上面这样还是有一个问题,就是em作为字体单位是会继承父元素字体大小的,上面的计算是假设所有元素的字体大小都以body的字体大小作为继承基准,然而实际的情况往往都不是这样的。举一个例子,如下DOM结构:

<body style="font-size:62.5%">
    <ul>
        <li style="font-size:1.2em">
            <a href="#" style="font-size:1.2em">导航菜单1</a>
            <span style="font-size:1em">我是一段测试文字</span>
        </li>
    </ul>
</body>

在默认情况下,我们期望<a>标签下面的字体大小应该为1.2em也就是12px,<span>标签下面的字体大小为1em也就是10px,但实际像上面这样我们得到的最终结果是<a>标签下面的字体大小为1.2 x 1.2 = 1.44em = 14.4px,<span>标签下面的字体大小为1.2 x 1 = 1.2em = 12px,这个就是因为em作为字体单位会继承父元素的字体大小,在本例中,由于给父元素<li>设置了字体大小为1.2em,所以浏览器在计算<a>标签和<span>标签的字体大小时就是上面实际所得到的结果。

这样一来其实em真正的计算公式就是:1 ➗ 当前父元素的font-size x 需要转换的像素值 = em值,就不是单纯地每次都去除以16px了,显然这种继承的方式在开发时会带来极大的不便。

rem

为了解决上面提到的em字体大小继承问题,又诞生出了一个新的CSS字体大小单位:rem,即 “root em”,它在字体大小与px进行换算时与em有着同样的换算规则,但唯一不同的是,rem只会以根元素的字体大小作为换算基准,而不会每次都从自己当前的父元素那里继承,在Web页面中根元素就是<html>,它的字体大小就是浏览器当前所设置的字体大小,默认情况下就是16px。

这样一来,按照上面提到的转换规则,还是上面的例子,把<body style="font-size:62.5%">赋值给<html>,即<html style="font-size:62.5%">,所有的单位改成rem,就可以得到我们的期望结果:<a>标签下面的字体大小应该为1.2rem也就是12px,<span>标签下面的字体大小为1rem也就是10px(此处只讲述原理,假设忽略浏览器的最小字体大小限制)。

rem很好地解决了em的字体大小从父元素继承所带来的不便。

浏览器兼容性

rem是CSS 3当中引入的单位,支持的浏览器有:Mozilla Firefox 3.6+、Apple Safari 5.0+、Google Chrome、IE9+和Opera11+,在现代浏览器或移动端,我们可以放心地使用rem来作为字体大小单位,但是如果你想使用rem这个单位,又想兼容低版本的IE浏览器,可以考虑px和rem同时使用,用px兼容低版本IE的效果,用rem实现现代浏览器的效果。


codeartisan1992
290 声望4 粉丝

追求极致、没事儿喜欢写写代码