[基础] EM 还是 REM?这是一个问题! - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
iFat3
V2EX    CSS

[基础] EM 还是 REM?这是一个问题!

  •  
  •   iFat3 2018-04-20 14:52:00 +08:00 3309 次点击
    这是一个创建于 2807 天前的主题,其中的信息可能已经有所发展或是发生改变。

    简言

    应用象EMREM这种相对长度单位进行页面排版是 WEB 开发中的最佳实践。在页面排版中较好应用EMREM,根据设备尺寸缩放显示元素的大小。这就使得组件在不同设备上都达到最佳的显示效果成为可能。

    但问题是究竟该用 EM 还是 REM 呢?关于这个问题一直存在比较大的争议。本文将会给大家介绍究竟什么是 EMREM 和如何进行两者的选择,以及结合两者优势构建模块化的 WEB 组件。

    注:本文内容简单,只面向初级开发人员,约 2500 字,阅读时间 5 分钟。

    1 什么是 EM ?

    em 是相对长度单位。它相对于当前元素字体尺寸,即font-size。举例来说,如果当前元素的字体是 20px,那么当前元素中的 1em 就等于 20px。

    h1 { font-size: 20px } /* 1em = 20px */ p { font-size: 16px } /* 1em = 16px */ 

    实际开发中,用相对长度单位(如 em)表示字体大小是 WEB 开发中的最佳实践。

    考虑下面的代码:

    h1 { font-size: 2em } 

    这里的 h1 元素字体大小究竟是多少呢?

    这时,我们需要根据<h1>父元素字体的大小,来计算<h1>字体的尺寸大小。如果父元素是<html>,而且<html>的字体大小是 16px。就可以计算出<h1>的字体大小是 32px,即 2*16px。

    用代码表示如下:

    html { font-size: 16px } h1 { font-size: 2em } /* 16px * 2 = 32px */ 

    设置<html>字体的大小一般来说都不是一个好主意,因为这样重写了用户浏览器的默认设置。相反,可以使用百分比值或者根本不声明<html>字体大小。

    html { font-size: 100% } /* 缺省 16px */ 

    对于大多数用户或浏览器,字体缺省大小是 16px (未做浏览器缺省字体尺寸设置)。

    em 还能用来指定除字体大小外的其它属性,象marginpadding等属性都可以用em来表示。

    考虑下面的代码, 对于<h1><p>元素,margin-bottom值应该是多少? (假设<html>的字号被设置为 100 %)。

    h1 { font-size: 2em; /* 1em = 16px */ margin-bottom: 1em; /* 1em = 32px */ } p { font-size: 1em; /* 1em = 16px */ margin-bottom: 1em; /* 1em = 16px */ } 

    上述<h1><p>的 margin-bottom 都是 1em,但是外边距结果值却不相同。上述现象的出现,是因为em是相对于当前元素字体的大小。由于<h1>中的字体大小现在设置为 2em, 因此<h1>中其它属性的 1em 值就是 1em = 32px。这里比较容易引起误解的地方。

    2 什么是 REM ?

    rem表示 root em,它是相对于根元素的长度单位。这里根元素就是<html>中定义的字体大小。这意味着任何地方的 1rem 总是等于<html>中定义的字体大小。

    利用上述相同的代码,我们用 rem 来代替 em,查看margin-bottom的计算值究竟是多少?

    h1 { font-size: 2rem; margin-bottom: 1rem; /* 1rem = 16px */ } p { font-size: 1rem; margin-bottom: 1rem; /* 1rem = 16px */ } 

    如上述代码所示,1rem 总是等于 16px (除非变更了<html>字体的大小)。rem的大小相较于em来说意义更直接明确,也很容易理解。

    3 REM 还是 EM?

    在项目开发中究竟是选用 rem 还是 em 一直以来争议不断。一些开发人员不使用rem,因为rem使组件不那么模块化。而另一些开发人员喜欢rem的简单性,使用rem处理所有元素。

    其实 emrem都有各自的优势和劣势,在实际项目开发中,应该结合使用两者,利用各自的优势,从而实现较好代码质量和显示效果。

    那么在具体的应用中如何在两者中做选择呢?有两条简单的指导原则:

    • 如果属性尺寸要根据元素字体进行缩放,则使用em
    • 其它情况下都使用rem

    上述规则太简单了。 为了更好的理解上述规则,我们就以一个简单的 header 组件为例,说明单独使用两者来实现组件遇到的问题,并体会结合使用两者所带来的优势。

    3.1 只使用 REM

    这里我们只使用rem来编写一个 header 组件,代码及运行结果如下:

    .header { font-size: 1rem; padding: 0.5rem 0.75rem; background: #7F7CFF; } 

    用 rem 实现 header 测试图 1

    接下来,网站需要一个尺寸更大的 header 组件。

    变更 CSS 代码如下:

    .header { font-size: 1rem; padding: 0.5rem 0.75rem; background: #7F7CFF; } .header-large { font-size: 2rem; } 

    运行结果如下:

    用 rem 实现 header 测试图 2

    从上述运行结果可以看出,文字的内边距(padding)过小,显示效果不协调。如果我们坚持只使用rem,只能变更 css 代码如下:

    .header { font-size: 1rem; padding: 0.5rem 0.75rem; background: #7F7CFF; } .header-large { font-size: 2rem; padding: 1rem 1.5rem; } 

    变更后运行结果如下:

    用 rem 实现 header 测试图 3

    上述代码及运行结果,虽然达到了预期的显示效果,但却违背了代码复用的原则。如果网站有多种尺寸的.header 样式,就要多次重复的定义内边距。重复的代码增加了项目复杂度,降低了可维护性。

    这时可以利用em可以变更上述代码如下:

    .header { font-size: 1rem; padding: 0.5em 0.75em; background: #7F7CFF; } .header-large { font-size: 2rem; } 

    运行结果请查看演示程序:

    演示代码

    如上述演示程序所示,当元素属性值的大小需要根据元素字体尺寸缩放时,就应该应用 em 来定义属性尺寸。这就是前述规则中的第一条规则。

    3.2 只使用 EM

    如果只使用em来定义上述组件,结果会怎样呢?

    我们变更上述代码如下(em替换rem):

    .header { font-size: 1em; padding: 0.5em 0.75em; background: #7F7CFF; } .header-large { font-size: 2em; } 

    为更接近实际,我们引入了<p>元素,并变更html代码如下:

    <div class="header header-large">名人名言</div> <p>简单是稳定的前提</p> <div class="header">名人名言</div> <p>简单是稳定的前提</p> 

    增加 p 元素 css 代码如下:

    p { padding: 0.5em 0.75em; } 

    运行结果如下:

    用 em 实现 header 测试图 1

    从上述运行经果中,不难看出.header-large部分的标题并没有和文本左对齐。而如果只使用em实现左对齐,则需要变更 CSS 代码如下:

    .header { font-size: 1em; padding: 0.5em 0.75em; background: #7F7CFF; } .header-large { font-size: 2em; padding-left: 0.375em; padding-right: 0.375em; } 

    变更后运行结果如下:

    用 em 实现 header 测试图 2

    上述代码及运行结果,虽然达到了预期的显示效果,但却违背了代码复用的原则。如果网站有多种尺寸的.header 样式,就要多次重复的定义左右边距。重复的代码增加了项目复杂度,降低了可维护性。

    解决上述问题的办法是结合使用emrem,即使用em定义上下边距,使用rem定义左右边距。变更后代码如下:

    .header { padding: 0.5em 0.75rem; font-size: 1em; background: #7F7CFF; } .header-large { font-size: 2em; } 

    运行结果请查看演示程序:

    演示代码

    3.3 EM 还是 REM 总结

    究竟是该使用em还是rem呢?答案应该是结合使用remrem。当属性值的大小需要根据当前元素字体尺寸缩放时,就选用em,其它的情况都使用更简单的rem

    4 em 及 rem 值的设定

    emrem 属性值都要经过计算转化成绝过长度单位。常用的字体尺寸用相对长度单位表示会很困难。看下面常用字体值的rem表示(基本字体尺寸是 16px ):

    • 10px = 0.625rem
    • 12px = 0.75rem
    • 14px = 0.875rem
    • 16px = 1rem (base)
    • 18px = 1.125rem
    • 20px = 1.25rem
    • 24px = 1.5rem
    • 30px = 1.875rem
    • 32px = 2rem

    如上述列表所示,上述尺寸值的表示及计算都不分的不便。为了解决上述问题要用到一个小技巧,即著名的 "62.5%"技术。具体请查看下述代码:

    body { font-size:62.5%; } /* =10px */ h1 { font-size: 2.4em; } /* =24px */ p { font-size: 1.4em; } /* =14px */ 

    通过 62.5%的设定,就可以很容易用em来定义具体属性的尺寸了( 10 倍的关系)。

    rem,则需要采用如下的方式:

    html { font-size: 62.5%; } /* =10px */ body { font-size: 1.4rem; } /* =14px */ h1 { font-size: 2.4rem; } /* =24px */ 

    5 响应式例子

    一个简单的响应式的例子,调整浏览器宽度查看演示效果。

    演示代码

    6 参考资料

    1. W3C:CSS Values and Units Module Level 3
    2. zellwk:REM vs EM The Great Debate
    3. sitepoint:Understanding and Using rem Units in CSS
    4. tutsplus:Comprehensive Guide: When to Use Em vs. Rem
    5. css-tricks:Confused About REM and EM?

    7 说明

    文中所述文字及代码部分汇编于网络。因时间不足,能力有限等原因,存在文字阐述不准及代码测试不足等诸多问题。因此只限于学习范围,不适用于实际应用。另emrem在较老的浏览器中存在兼容性问题。

    目前尚无回复
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2578 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 05:14 PVG 13:14 LAX 21:14 JFK 00:14
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86