浅析css中的em rem

em px rem 相对单位


写了很多css代码,但一直都是在使用“px”来设置元素的相关属性,偶尔也使用“em”,基本很少使用rem。主要原因是,对其了解的不深,往往只知道一点概念性的,所以特意查找资料重新学习一回。今天整理了一份文章与大家分享,也算是记录自己点滴的学习,希望能对大家有所帮助。


px:绝对单位,按像素展示

"px"是我们用的最多也是最常见的,但是使用它虽然方便,但会带来一些小小的问题。不知道你们有没有这样的经历,辛辛苦苦把页面的代码码完了,在自己的电脑能正常显示,换一个电脑整个页面崩溃了(内心也崩溃了)。。。
接着就会想到比较熟悉的百分比来写css,但百分比到底是谁的百分比?有人说是相对于父元素的宽度(width),也有人说不仅仅相对于这个,相信大家也会有点迷糊吧!百分比布局虽然好用,但搞清楚是相对于谁的百分比非常重要,来点干货:

  • 参照父元素宽度的元素:padding margin width text-indent
  • 参照父元素高度的元素:height
  • 参照父元素属性:font-size line-height(如果自身有font-size属性,相对于自身)
  • 特殊:相对定位的时候,top(bottom) left(right) 参照的是父元素的内容参照的是父元素的内容区域的高度与宽度;而绝对定位的时候参照的是最近的定位元素包含padding的高度与宽度;对于position:fixed的元素,则一直基于body元素

这么很容易记混乱,当然用熟练了也不是什么事!!(具体的栗子我就不写了)


em:相对单位

除了"px"和百分比布局,第三个想到的就是“em”了。em也是一个相对单位,既然是相对单位,相对的计算必然会有一个参考物,那么这里相对所指的是相对于父元素的font-size属性。一般来说,如果没有特意设置font-size,那么就是相对于body的font-size,即16px;
比如说:如果在一个div中设置字体大小为"16px",此时div的后代将继承它的字体大小(除非重新在其后代元素中设置font-size),也就是说此时1em = 16px,如果你设置了子元素的width为0.75em,那么在浏览器中显示的width为12px0.75 * 16px = 12px。是不是相对于百分比来说更不容易混淆,这个转化可以总结为一个公式:

元素自身没有设置字体大小时,元素的width、height等值按下面的公式转换:
需要转换的像素值/父元素的font-size = em值
注:若子元素设置了font-size(设置为em),子元素的font-size值是根据父元素字体大小来设置,其它的按照自身的字体大小设置。

你可能会说这个计算好麻烦,确实,写css估计要带一个计算器。。
一个小技巧:

我们经常会在页面上看到根元素写的font-size:62.5%,这样em就相当于 16px * 62.5% = 10px ,也就是说12px = 1.2em,16px = 1.6em,即只要将你原来的px数值除以10,换上em单位即可。
html,body{font-size:62.5%;}

但如果嵌套了多个元素,要计算它需要明确每个父元素的font-size 值,这是件很头疼的事情,这种情况下css3就出现了rem.


rem:相对单位,“root em”
rem是相对根节点即html的字体大小来计算,属于css3新加属性,chrome/firefox/IE9+支持。//目前用的比较多的也是最流行的。
之所以前端做移动端普遍默认用rem或em,是因为可以通过js控制根元素(或者用@media)来达到适配各种分辨率的字体大小的效果。

rem在移动端应用可参考淘宝的页面http://m.taobao.com (html的font-size通过动态计算获取)

介绍几种常见的使用rem的方案:

  • 简单版:页面基准750px,html font-size的计算:
    (function(doc,win){
        var htmlFont = function(){
            var docEl = doc.documentElement,
            w = docEl.clientWidth,
            resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
            f;
            f = w/7.5;
            w > 750 ? docEl.style.fontSize = 100 + "px" : docEl.style.fontSize = f + "px";
        }
        htmlFont();
        win.addEventListen("resizeEvt",htmlFont,false);
    })(document,window)

注: 需要设置meta标签,缩放比为1:1,把上面这段js放到html 的head标签中


  • 进阶版 --高清方案
    把这段js放到HTML的head标签中即可,注:不需要手动设置viewport,该方案自动帮你设置,通过修改viewport 属性放大缩小 initial-scale
!function(e){function t(a){if(i[a])return i[a].exports;var n=i[a]={exports:{},id:a,loaded:!1};return e[a].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var i={};return t.m=e,t.c=i,t.p="",t(0)}([function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var i=window;t["default"]=i.flex=function(e,t){var a=e||100,n=t||1,r=i.document,o=navigator.userAgent,d=o.match(/Android[\S\s]+AppleWebkit\/(\d{3})/i),l=o.match(/U3\/((\d+|\.){5,})/i),c=l&&parseInt(l[1].split(".").join(""),10)>=80,p=navigator.appVersion.match(/(iphone|ipad|ipod)/gi),s=i.devicePixelRatio||1;p||d&&d[1]>534||c||(s=1);var u=1/s,m=r.querySelector('meta[name="viewport"]');m||(m=r.createElement("meta"),m.setAttribute("name","viewport"),r.head.appendChild(m)),m.setAttribute("content","width=device-width,user-scalable=no,initial-scale="+u+",maximum-scale="+u+",minimum-scale="+u),r.documentElement.style.fontSize=a/2*s*n+"px"},e.exports=t["default"]}]);  flex(100, 1);

代码优势:(不需要理解每一行的意思,这是经过压缩的)

  • 引用简单,布局简便

  • 根据设备屏幕的DPR,自动设置最合适的高清缩放。

  • 保证了不同设备下视觉体验的一致性。(老方案是,屏幕越大元素越大;此方案是,屏幕越大,看的越多)

  • 有效解决移动端真实1px问题(这里的1px 是设备屏幕上的物理像素)

    想要搞清楚移动端适配问题,可访问https://github.com/riskers/blog/issues/17

分享一个关于移动端屏幕,设备像素,css像素的链接:https://riskers.github.io/share/share/flexible.htm#403

只写了一点关于rem的使用,具体的以后再补!!!

你可能感兴趣的:(浅析css中的em rem)