CSS3 的字体大小单位「rem」到底好在哪? CSS3 新增了相对单位rem,使用 rem 同 em 一样皆为相对字体大小单位,不同的是 rem 相对的是 HTML 根元素。但是使用 rem 的优势到底在哪?
CSS3 的字体大小单位「rem」到底好在哪? - 知乎 https://www.zhihu.com/question/21504656
作者:王佳欣
链接:https://www.zhihu.com/question/21504656/answer/85135845
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
以需求来介入:都知道现在手机屏幕分辨率越来越多了,假设我们的网页需要适配的iPhone4(320px),iPhone6(375px),iPhone6 Plus(414px)。我们的需求是,当用户浏览网页时,根据屏幕的尺寸,来向用户展示更适合用户的文字、图片、按钮大小。(1)iPhone4的时候,希望网页的内容文字大小12px=12*(320/320)px,按钮的大小是240px。(2)Iphone6的时候,虚妄网页的内容文字大小14px=12*(375/320)px,按钮的大小是280px,等比缩放。(3)Iphone6 Plus的时候,虚妄网页的内容文字大小15.5px=12*(414/320)px,按钮的大小是310px,等比缩放。以前的做法在rem概念没引入前我们的做法是,以最小的屏幕(iPhone)做一版数据出来,然后通过js去控制viewport 的 initial-scale (网页缩放比例)。如:iPhone4下:<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0 />
那么对应的到了iPhone6需要调整缩放比例 initial-scale=375/320 =1.18<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.18 />
同理到了iPhone6 Plus对应的应该是 initial-scale=414/320 =1.30<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=3.0 />早期【天猫】移动端也是用用这样的方法实现的。能满足我们的需求。缺点是:这样做会使得,因为initial-scale越来越大,相当于拉伸网页,而使得在大屏幕的移动端设备下,文字、图片会变模糊。rem做法现在【天猫】的做法就是用rem来做。rem(font size of the root element)是指相对于根元素的字体大小的单位(可以联想一下em)。也就是比如我定义:html{ font-size:14px}那么如引用.test-box font-size/width/height 设为2rem的话就相当于 2*14px。也就是.test-box{
font-size:2rem;
/*font-size:28px;*/
/*2*14px/
}我们可以理解为,一旦根节点html 定义的 font-size 变化,那么整个网页中运用到 rem的也会变化。我们来看一下【淘宝】的实例:先展示效果,可以看到页面上的文字、按钮、logo都有相应的变大调整。iPhone4下的效果。<img src="https://pic1.zhimg.com/50/f7f93cf19e0fdae9419631ae15ed7fae_720w.jpg?source=1940ef5c" data-rawwidth="373" data-rawheight="613" class="content_image" width="373"/>iPhone6下的效果。<img src="https://pic3.zhimg.com/50/7cf8dc9712b8be09316db94080aaab60_720w.jpg?source=1940ef5c" data-rawwidth="436" data-rawheight="804" class="origin_image zh-lightbox-thumb" width="436" data-original="https://picx.zhimg.com/7cf8dc9712b8be09316db94080aaab60_r.jpg?source=1940ef5c"/>iPhone6 Plus下的效果。<img src="https://picx.zhimg.com/50/16e0263052fafdd249058ea7e8950e4b_720w.jpg?source=1940ef5c" data-rawwidth="461" data-rawheight="867" class="origin_image zh-lightbox-thumb" width="461" data-original="https://picx.zhimg.com/16e0263052fafdd249058ea7e8950e4b_r.jpg?source=1940ef5c"/><img src="https://pic1.zhimg.com/50/16e0263052fafdd249058ea7e8950e4b_720w.jpg?source=1940ef5c" data-rawwidth="461" data-rawheight="867" class="origin_image zh-lightbox-thumb" width="461" data-original="https://picx.zhimg.com/16e0263052fafdd249058ea7e8950e4b_r.jpg?source=1940ef5c"/>(图片上传太慢,图片上传不了啊.........,用代码展示)iPhone4下html节点font-size<html data-dpr="2" style="font-size: 64px; width: 100%; height: 100%; overflow: hidden;">iPhone6下html节点font-size<html data-dpr="2" style="font-size: 75px; width: 100%; height: 100%; overflow: hidden;">iPhone6 Plus下html节点font-size<html data-dpr="2" style="font-size: 82.8px; width: 100%; height: 100%; overflow: hidden;">具体大家可以去看【淘宝】的移动端页面的案例。给大家介绍一片写rem的详细文章。腾旭ISUX的一篇文章。web app变革之rem编辑于 2016-02-06 16:44赞同 10214 条评论分享收藏喜欢收起薛昊设计师 关注17 人赞同了该回答rem的优势大家说了不少,谈谈rem的劣势一个App里native界面和Web界面混合使用时,rem在不同尺寸屏幕上的适配与native界面适配不一致。这样会导致在部分机型及屏幕上,一个App内同一个控件在native界面和Web界面上的尺寸不一致。比如:列表页是用native做的,详情页是用rem做的,设计师希望列表页与详情页字号都一致,换算rem时如果用iPhone5的尺寸换算,那么在Plus上,详情页的字号会大于列表页。rem在多屏幕尺寸适配上与当前两大平台的设计哲学不一致。iOS与Android平台的适配方式背后隐藏的设计哲学是这样的:阅读文字时,可读性较好的文字字号行距等绝对尺寸数值组合与文字所在媒介的绝对尺寸关系不大。(可以这样简单理解:A4大小的报纸和A3大小甚至更大的报纸,舒适的阅读字号绝对尺寸是一样的,因为他们都需要拿在手里阅读,在手机也是上同理);在看图片视频时,图片、视频的比例应该是固定的,不应该出现拉伸变形的情况。而rem用在字号时,使字号在不同屏幕上的绝对尺寸不一致,违背了设计哲学。发布于 2016-03-14 20:24赞同 1712 条评论分享收藏喜欢楚狂人不务正业 关注22 人赞同了该回答来个不太专业的回答。本人从事it也一年有余了。字体大小的单位有很多,W3C上有,我就不多说。我们最常听说的是px和em。px是什么呢。比如我的屏幕是1366*768,那么一个网页上说我的这个标题需要40px,那么我就腾出40px来显示它。可是,我使用了 缩放呢?据说,以前是改变不了字体的,所以,就有了网上疯传的使用em来代替px。可是em是相对的,比如你把body的font-size定义为50%,一般地会是8px。那么你在body里字体大小就是1em=8px了。可当你定义了一个div,然后把字体设置成了75%,请问,现在的1em等于多少?这个时候你会发现,原来他继承了body的值,现在字体更小了,变成了6px!这是我们希望的吗?大多数时候,我都忘了我在某处定义了1em等于多少!我需要知道别人写的1em等于多少吗,我要继承这个属性吗?我数学不好,不想计算啊。所以rem的好处出来了。发布于 2013-08-19 14:44赞同 22添加评论分享收藏喜欢PlayStation广告不感兴趣知乎广告介绍PS Plus八月会员升级限定福利来袭!超多游戏免费畅玩!PS Plus 8月福利来袭!《YAKUZA》系列、《DEAD BY DAYLIGHT》、《Tom Clancy's Ghost Recon》系列和《Bugsnax》等作品免费畅玩查看详情RR AA徐志雷五届TI,第四第六第四第九第六 关注6 人赞同了该回答在前几年,为了统一不同屏幕尺寸下的浏览效果,rem可以说是非常好用的一个属性,通过针对不同视口设置不同的body font-size,可以让各种千变万化的屏幕获得相同的浏览体验。但是在今天,rem这个属性应该是不太适合现如今的前端开发环境了。首先,今天大屏手机已经成为市场主流,大部分手机屏幕都在5寸左右,安卓阵营通常是小屏4.6英寸,普通屏幕5.15英寸,大屏5.5英寸。苹果阵营一般正代机4.7英寸,plus5.5英寸。如果统一按照px来进行页面设计,浏览效果不会相差太多。比较特殊的小屏机iphone se和各种6英寸以上的机型只要没有严重的兼容性问题也不大。其实,关于rem和px,主要的矛盾就是,当手机屏幕变大的时候,是看的更多,还是看的更大但一样多。如果直接上rem,原本为5.15英寸屏幕设计的页面,在4英寸的iphone se上,各种元素均会缩小,字体以及图标会难以阅读和点击。还有,现如今有更好的vw,vh属性可以利用,vw属性作用可以看做是增强版的rem,简单粗暴。我现在个人进行前端开发,如果设计人员没有指明,一般以px为主,vw为辅。rem个人基本上不用了。发布于 2017-08-08 08:27赞同 61 条评论分享收藏喜欢xcatliuA cat who writes code 关注说用 rem 然后把 html 设置成 font-size:10px 的,没有遇到这个 bug 吗?html 的 font-size 设置为 10pxp 的 font-size 设置为 2remp 的 margin 设置为 2rem结果 p 的 font-size 被渲染成了 20px,p 的 margin 被渲染成了 24pxCodePen: https://codepen.io/anon/pen/peKKZY<img src="https://pic2.zhimg.com/50/v2-2fa3a8c5bf637eb700378b599723e3ea_720w.jpg?source=1940ef5c" data-rawwidth="1018" data-rawheight="572" class="origin_image zh-lightbox-thumb" width="1018" data-original="https://pic1.zhimg.com/v2-2fa3a8c5bf637eb700378b599723e3ea_r.jpg?source=1940ef5c"/>相关问题:rem works fine with font-size but does NOT work fine with margin if I set 10px font-size to html tagcss3 - css rem 字体问题 - SegmentFault发布于 2017-06-26 17:21赞同7 条评论分享收藏喜欢知乎用户6 人赞同了该回答你可能会给 html/body 元素定义一个字体大小,来作为整个页面的参考值,我们后面称它为 base 好了。老板说:这部分是正文,字体要大一些,行间距也大一些,看着明显。你就可以给 article 元素设置 1.4 倍的字体大小(1.4em),这时候,正文里的标题 h2 可以设置成 2em,这时候它的字号已经是 base 的 2.8 (1.4*2) 倍了。然后设计师跑过来说:图片下面的注解字体太大了,跟正文无法区分。你想把它设置成和 base 一样大,是 0.714em (1/1.4) 吗?NO,是 1rem。因为 em 是相对于父元素的倍数,所以你可能在许多层嵌套的 em 中找不到一个固定值,rem 就是可以随时拿来用的一个固定参考值。———————————为什么建议网页的全部 *文本* 都用 em/rem 来设置大小呢?有了这个 base 变量,就可以只修改一个值,来改变所有文字的大小了。因为它们都是 base 的倍数。就像浏览器提供的页面缩放功能那样,不过这里是只缩放文本。再结合 media query,就可以控制不同屏幕上有不同的字号了(14px 在某些设备上有点小吧) 。编辑于 2015-05-21 09:53赞同 61 条评论分享收藏喜欢知乎用户31 人赞同了该回答rem单位其实是很棒的,但我觉得现在主流的用法不太合适。方案有个根本的问题要先回答,为什么要让一稿设计在不同设备上等比缩放呢?我相信很多时候这是设计师的要求,那这个设计师很可能是在偷懒。充分了解各种设备,就应该知道不同尺寸的屏幕本身就有各自的定位。7 plus本来就应该要比7有更大的视野,而不是如此粗暴地让大屏手机用户看到老人机一般的界面。现在最常见的rem用法是根据屏幕大小改变根元素的font-size,从而等比缩放界面元素。如果用户买大屏手机是为了更大视野,这么做显然让他们失望了;如果他们是因为视力不佳需要更大的字,他们早就设法在系统级上把字号调大了。最理想的方案应该是(我改天再研究下能不能实现):根元素的字号不要去人为改变,应该根据系统级的字号设置缩放,而不是屏幕宽度。编辑于 2017-01-29 23:59赞同 311 条评论分享收藏喜欢木其君个体户 关注13 人赞同了该回答用在适配不同尺寸屏幕时,css中使用rem作为单位,代码就只需要写一遍。在适配部分只需要如下:@media only screen { html { font-size: 30px; } }@media only screen and (max-width: 479px) and (min-width: 321px) { html { font-size: 15px; } }@media only screen and (max-width: 320px) { html { font-size: 13px; } }修改方便;节省服务器流量。发布于 2015-05-19 22:23赞同 138 条评论分享收藏喜欢猫5号鄙人前端码农,人称猫哥者也 关注1 人赞同了该回答rem是一种简单粗暴解决不同屏幕下视图的区别的一种方案,其实就相当于一种hack,就是因为简单粗暴有效,所以广泛使用,形成一种共识,甚至带来对rem这个单位的误读,个人不建议用rem进行布局,移动设备浏览器上的px其实就是dp,已经是最佳对不同尺寸手机的最佳处理方案,特别涉及到跨平台的native开发,px不会有任何差异,反倒rem,会带来开发的障碍。引用 @大米干饭 的说法,其实归根到底就是大屏幕的作用问题,我偏向于看更多内容,所以我是不用rem派的编辑于 2017-12-19 17:22赞同 12 条评论分享收藏喜欢知乎用户难道不是只改一个值,适配不同屏幕的吗?感觉挺好的发布于 2016-06-17 08:10赞同添加评论分享收藏喜欢知乎用户漫画等 6 个话题下的优秀答主8 人赞同了该回答最大的好处是计算方便。比如我根元素设置字体大小10px,一个容器里正文想用14px,容器就设1.4rem,标题想要20px,那么就设2rem。如果使用em,那么标题就要算一下了,20/14=1.4em,如果用2em,就变成28px了。发布于 2013-08-19 14:32赞同 87 条评论分享收藏喜欢三喵maiev.org 关注2 人赞同了该回答对absolute布局做移动端适配时,如果用百分比高宽的话,计算出的高度是屏幕高度的百分比,计算出的宽度是屏幕宽度的百分比。屏幕高宽比一变化,元素就会变形,正方形变长方形,圆形变椭圆。使用rem的话,高宽都根据html节点上的字体大小做换算,就不会变形。不过rem也有缺点,具体用哪种方法做适配还是根据实际情况,rem 百分比 px都有用武之地。发布于 2015-05-27 22:40赞同 21 条评论分享收藏喜欢路条编程编程爱好者、赠人玫瑰 、手有余香 关注<img src="https://picx.zhimg.com/50/v2-640b714b792ba317bd7e215d77521498_720w.jpg?source=1940ef5c" data-caption="" data-size="normal" data-rawwidth="1920" data-rawheight="1280" class="origin_image zh-lightbox-thumb" width="1920" data-original="https://pic1.zhimg.com/v2-640b714b792ba317bd7e215d77521498_r.jpg?source=1940ef5c"/>在这篇文章中,我会讨论一些CSS中REM的用例。首先我会介绍关于CSS属性和值的一些必要的背景知识,然后我会对比绝对长度值和相对长度值。REM是相对长度值。最后两部分,我会介绍在字体大小方面REM的用处,如何通过REM实现响应式网页。让我们开始吧!基础知识这部分我会通过介绍一些CSS知识来引入。什么是CSS?CSS(层叠样式表)通过属性和值幻化出来网页上的美学魔法。假设你需要通过一个精雕细琢的边框来增强图片的美感,你希望这条边框是条黑色实线。这时border就是你需要选择的属性,而solid就是这个属性对应的值。在CSS中这两个关键字帮助你创建出理想边框。你或许会猜想一定还有更多各种各样的值,毕竟仅仅一条实心线做的边框是不足以装点你的页面的。border属性确实接受不同的关键字、颜色和长度值。 这是因为 border 是 border-width、 border-style 和border-color的缩写。因此,除了分别声明每一个属性,border还可以一次性接受所有这些属性的值,如下:border: 2px solid #ffff00;使用边框缩写属性在上面的代码片段中,2px是边框长度的值, solid 是边框样式的一个关键字, RGB16进制#ffff00 代表黄色。 于是我们就创造了一个还不错的边框。(好啦,我知道不太美观,但你懂我的意思!)在正式介绍REM之前,还需要说明一下,不同的属性对应不同的与之匹配的值。这些值的合集被称作值类型或者数据类型。让我们来借助上个例子说明这个概念。color就是一种值类型,RGB16进制值#fff00(代表黄色)是这个值类型的一个具体值。为了帮助理解,你可以把值类型看作类型,具体的值看作这些类型的个例。所以一旦你不知道某个属性接受什么类型的值,搜索值类型,就可以获得答案。CSS中的REM是什么?REM就是一种值类型,R代表的是Root(根)。REM是一种长度类型的值/数据。另一种长度类型就是我们的老朋友像素(px)。任何接受长度作为值的属性都可以使用REM:其中包括margin、padding等。你可能会好奇,为什么我们要使用REM,答案就在下一章。CSS中的相对长度值和绝对长度值在CSS中有两种长度值:绝对长度值和相对长度值。绝对长度值绝对长度值包括: px (1英寸的九十六分之一), in (1英寸) 和 cm (相当于 37.8px 或 25.2/64英寸)。 可以在MDN查看更多例子。当使用绝对长度值的时候,你可以确保任何情况他们的大小几乎保持不变。当你知道输出大小的准确尺寸时它就派上用场,如在整页模式下。但如果有多种屏幕样式需求的话,绝对长度值就不奏效了。更别说因为个人喜好或者浏览器的无障碍性造成的浏览器的不同设置。相对长度值相对长度值代表另一类值,包括:REM、 EM和 vw。 之后我们会详细讲解REM,在这里我先简单说说其他的单位。EM的大小定义:在处理font-size属性时,与父元素的字体大小有关;在处理其他一些属性,如height时,与元素自身的字体大小有关。vw 代表窗口宽度的1%。 也就是说如果你把width设置为10vw,元素就会占窗口10%的宽度。 其他长度参见这里。相对长度值的优势非常明显,可以用它们来构建响应式网站。即网站会根据你的设定,有规律地自适应屏幕大小。根EM(REM)和根字体大小REM的大小取决根元素的字体大小。根元素通过伪类:root或者html选择器选定。因此1rem继承了根元素font-size的大小。 也就是说在整个CSS代码中1REM的大小保持不变。 如果用户没有修改根元素的大小,字体大小默认为 16px。请看下面的例子:html {
font-size: 18px; // default value would be 16
}
h1 {
font-size: 2rem; // 2 * 18px = 36px;
}反推出 2rem 等于多少 px并不难, 但为了计算设置为 1.125rem (即 16 * 1.125: 18px)的副标题的像素大小,你真的要在手边准备一台计算器吗?好在有一个简化方法。记住你可以用百分比来设定根元素的字体大小,所以开发者们发现根元素默认大小的62.5%等于 10px。这样计算就变得容易多了:html { font-size: 62.5%; // 16px * 0.625 = 10px; } h1 { font-size: 1.8rem; // 10px * 1.8 = 18px; }考虑到无障碍性,font-size必须设定为REM(或者其他相对长度值)。 因为在一些浏览器中,如果长度值为px,即便浏览器设置改变了,字体大小也不会改变。对于视力障碍人群来说,或许需要放大4倍才能看清文本。使用REM可以确保文字按需呈现大小,因为这样的话,文字大小由用户选择的字体大小默认值来决定。响应式网页设计中的REM响应式网页设计是一个综合性话题,包含不同的方面的内容。freeCodeCamp有两个相关课程。(如果感兴趣,你可以查看https://www.freecodecamp.org/learn)接下来我会讲解REM是如何辅助构建响应式网站的。在这篇文章中可以看到,谷歌鼓励将一行文字的词数控制在10个以内,这个规定符合经典的可读性理论。谷歌建议在确定的断点使用媒体查询,这样内容或文本行的宽度就不会太长,给用户提供最佳的阅读体验。以下例子,灵感来源Adrian Sandu的文章 :html {
margin: 0;
padding: 0;
font-size: 62.5%;
}
#divOne {
width: 100%;
box-sizing: border-box;
font-size: 1.6rem;
padding: 0.5rem;
background-color: lightblue;
}
@media (min-width: 27.1875rem) { // first breakpoint: 27.1875*16px= 435px
p {
font-size: 1.6rem;
}
#divOne {
width: 41.8rem;
background-color: yellow;
margin: auto;
}
}
@media (min-width: 40.78125rem) { // 1.5 * first breakpoint: 653px
p {
font-size: 2.4rem; // 1.5 * font-size first breakpoint
}
#divOne {
width: 62.7rem; // 1.5 * width of first breakpoint
background-color: green;
padding: 0.75rem; // 1.5 * padding of first break point
margin: auto;
}
}响应式网站例子你可以在 codePen 查看效果。可以调整窗口大小观察布局的变化。你可能会注意到在上面的例子中,在媒体查询的定义中的 1rem始终为16px。但在媒体查询代码块中, 1rem的大小随着根元素font-size的值变化,根元素为62.5%的16px,所以这里的1rem为10px。出现这种情况,是因为媒体查询代码块中的REM始终继承浏览器默认字体大小,通常情况下是16px。一旦用户更改了默认设定,REM就会随之变化,以适配用户指定的一些无障碍设定需求。上面的代码采取了手机优先的设计策略。我把第一个断点定义为435px。注意在这个断点内,文本的宽度始终不变化,但是文本周围的留白成比例改变,约为之前的1.5倍。下面是分步骤图解:当窗口宽度小于435px时的布局:<img src="https://pica.zhimg.com/50/v2-718e4c1c62950f92330cd8828bca048a_720w.jpg?source=1940ef5c" data-caption="" data-size="normal" data-rawwidth="565" data-rawheight="482" class="origin_image zh-lightbox-thumb" width="565" data-original="https://pic1.zhimg.com/v2-718e4c1c62950f92330cd8828bca048a_r.jpg?source=1940ef5c"/>容器占手机屏幕宽度的100%当窗口宽度介于435px与652px之间时的布局:<img src="https://pica.zhimg.com/50/v2-c28e54e13416768db6745fe88860376c_720w.jpg?source=1940ef5c" data-caption="" data-size="normal" data-rawwidth="691" data-rawheight="479" class="origin_image zh-lightbox-thumb" width="691" data-original="https://pic1.zhimg.com/v2-c28e54e13416768db6745fe88860376c_r.jpg?source=1940ef5c"/>容器中的文本大约10个词一行当窗口宽度大于 652px时的布局:<img src="https://pic3.zhimg.com/50/v2-a287672a6b97f237621458f7a547f2ab_720w.jpg?source=1940ef5c" data-caption="" data-size="normal" data-rawwidth="1000" data-rawheight="542" class="origin_image zh-lightbox-thumb" width="1000" data-original="https://pica.zhimg.com/v2-a287672a6b97f237621458f7a547f2ab_r.jpg?source=1940ef5c"/>总结在这篇文章中我们探索了CSS中的REM。我们可以利用相对长度值REM来有逻辑地规划网站中的字体大小。REM也可以适应无障碍需求,满足更改了默认font-size用户的需求。最后我们也探索了如何使用REM构建响应式网页,同时适配用户改变浏览器默认设置后的变化。在写这篇文章的时候,我借鉴了以下内容:通过例子学习CSS单位– Em, Rem, VH, and VW 作者 —— Joy ShahebCSS单位指南: 解释CSS中的em、remvh、vw等来自freeCodeCampCSS单位对抗: EM和REM之间的战斗 作者——ZAYDEKCSS中的REM: 理解并使用REM单位 作者——Adrian SanduCSS的值和单位、长度、字体大小 来自MDN无障碍响应式设计 作者—— Dave Gash、 Meggin Kearney、Rachel Andrew 和 Rob Dodson响应式布局基础 作者—— Pete LePage 和 Rachel Andrew感谢阅读!