你可能听过,每当要定义页面上元素的尺寸时,别人都说你应该使用 emrem ,而不是px

你也可能听过一些像“无障碍访问”、“流式布局”和“弹性布局”之类的概念并认为这确实是个不错的想法。甚至有点开始觉得只使用像素定位太out了。

如果是这样,我有一些好消息告诉你,可以将你从这些讨厌的单位中解救出来。

那就是使用像素定位是个完全没有问题的选择,在定义尺寸方面它甚至可以表现的非常优异。


理想状态下,大家不需要我提供什么证据就会相信我的理论。但这是不现实的,所以以下我勉为其难地给出了我的理由,来告诉你为什么使用这些单位没有太大意义。

1 提高可访问性

或更具体的说:“使用rem可以让你的布局在用户手动缩放页面时展现的更好”。

现在人可能真的太过于看重可访问性了。我某天在一个YouTube评论上看到有人说希望找到一个比WGAG标准更具体一点的“可访问性测试工具”。

行,我现在就给你做一个:

accessibility testing device

“像一个不能去访问你页面的人那样去访问你的页面”

我同时出售30寸大屏专用版(一条毛巾),以及通用解决方案,一个为你脑袋准备的枕头。

我的观点:你不需要深入的知识和花哨的工具去测试rem和em是否可以提供“更好的可访问性”,只需要想象一下你是位视力不好的人。如果你想象力匮乏,可以试着把你的屏幕包几层保鲜膜。

当然可访问性不单单是指可阅读性,但这里我们先只讨论这点。

好现在问问视力不好的你,下面三项哪个可以帮你提高可阅读性:

  1. 更改操作系统的字体大小,这会让所有的文字、菜单、时钟、其他应用和网页字体变得更大。
  2. 放大那些字号特别小的页面。
  3. 改变浏览器默认的最小字号。

我不知道你会选哪个,但如果我阅读小号字很吃力的话,我会直接调大操作系统的字号,然后彻底忘记它的存在。

(做演示时这么干也很方便)


我们来深入的研究一下…

本着研究精神,我写了一个小的demo页(如果谁抑制不住自己的好奇心,这里是jsbin地址)。

页面上三段的html和css是一样的,唯一不同的是它们所用的单位,最上面那个用的全是px,中间的全是em,最下面的全是rem。

在默认缩放情况下(1em = 16px)它们看起来是这样的:

default zoom

字体很难阅读?那我只能表示同情了。

现在,将操作系统的字号放大为150%,Windows上用Chrome看是这样的:

default zoom

感觉就像是脸贴近了点。

接下来,把操作系统的字号还原回100%,调大浏览器的字号。

对某些网站来说主导航栏用12px的字号是可接受的,因为这样可以更好的利用屏幕空间,而不是去思考如何缩短命名,但对亚马逊来说,13px的默认字号,12px的主导航栏字号显然就不合适了。

幸运的是浏览器对老年人们还是友好的,你可以crtl加滚轮去缩放页面。

我视力超好,但有时我也会缩放页面,还有Chrome的开发者工具,它的默认字号是12px,但我也不知道为啥原谅它了。

(小广告:如果你觉得维基百科的字号有点小,或不喜欢它水平方向占满整页的排版,我写了一个叫Skinny 的Chrome 插件,可以调大默认字号顺便让每行变短点。)

扯远了,现在来看下浏览器页面放大到150%时的效果:

default zoom

浏览器的UI变小了,但页面内容看上去是一样的。

最后来看看改变浏览器的默认字体大小,先试试火狐,这是没缩放的时候:

default zoom

将最小字号设为20px之后:

default zoom

使用px的nav标签变窄了,header标签的字体变大了一点点。

然后用Chrome将字体大小设为“大”。

default zoom

终于可以看出点区别了,因为title标签里的字体是18px,以及侧边栏nav标签的宽100px是写死的,所以它们大小都没有变。

你可能会觉得这是rem的伟大胜利,但并非如此。

虽然没有证据表明人们到底有没有十分依赖改变浏览器字体大小,但却有些确凿的事实:

  • 改变浏览器字体大小对facebook, youtube, amazon, twitter, medium, linkedIn, eBay等网站并没有效果,Alexa排名前100的网站我还只扫了一半。
  • 所以如果某人阅读16px字体有障碍,他肯定会用其他方法去访问以上网站。
  • 而且改变浏览器字体大小显然对操作系统的其他部分不起作用。
  • 所以可以推断如果某人阅读16px字体有障碍,但他又想去看Excel菜单、电子邮件、系统设置、文件夹等,他需要去找个其他方法来解决这个问题。

这就很明显了,显示世界中改变浏览器字体大小根本毫无用武之地。所以在决策时我也不会考虑这一设置。


“更好的可访问性”论述完毕,现在来看看…

2 使用rem/em时的断点设置

换句话讲,如果用px去定义断点,它们就是写死的,不会随着页面缩放而改变,因为px就是固定的像素不是吗?

好吧那都是骗人的(可能过去某个时候是真的,但那已经是历史了。)

我的demo页断点设的是600px,中间的是37.5em,最后一个是37.5rem。默认情况下它们都是等于600px的。

小于断点的时候,发送者和主题文本是竖直排列的,大于的时候是水平排列。

用IE11来试试,将页面放大为150%,然后把浏览器拖成900px宽(600px的1.5倍)。

你认为IE11会怎么判断呢?

它会认为断点任何时候都是600px,然后显示大屏方案;还是自适应断点到150%,显示小屏方案(文本竖直排列)?

好吧,我很惊奇的发现,IE在我缩放页面的同时也缩放了断点值。

default zoom

窗口宽度900px。

这是IE11,那其他浏览器呢…

Safari也很让我觉得奇怪。这次我把窗口调的比900px稍微小点。现在窗口宽度应该是比断点的600px宽多了,但在150%的缩放下,所有三段全排版成了断点以下的格式。

default zoom

所以不用担心如果用px断点不会跟着缩放的问题。或者你可以先去找一个不缩放px的浏览器,然后根据其市场份额再做决定。如果你必须支持IE8,然后发现它不缩放断点,那你就有了一个合法的理由去使用rem了(当然IE8既不支持媒体查询也不支持rem,但没必要在这死磕了)。

3 使用em控制文本周围的“动态”间距

这几乎是个好主意,我了解支持者们都是怎么说的,“用em设padding,这样如果要改的话就只用修改font size了”。

我懂的,真的。但我倾向于做的更精确些,比方,设置一个按钮的font-size和padding让它在大屏上刚好60px高,小屏上刚好50px,视觉上完美契合我60px/50px的标题栏。

而且如果我的设计稿是来自一位专业的设计师,没有哪一位会不在乎一个按钮的精确大小的,这样的设计师存在吗?

但如果你是自己设计页面,而且完全不在乎按钮具体多高,段落文本离标题栏多远,并且希望当字号改变时旁边的间距也随之增加,那么margin/padding用em去设就正好适用了。


现在,再来说一个更莫名其妙的劝你使用rem,em的原因(我也不知道我为什么要给这些标题列序号)。

4 生成一个单改变根元素字号就可以改变整体大小的模块

这句话来自几周前的一篇博客文章,用em设计一个响应式网站

文章详细解释了通过使用rem和em的组合,你可以生成一个只需改变根节点元素的字体大小就能缩放成各种不同尺寸的组件。

这听上去很有道理,就跟“如果你经常杀人,那么开车前拿把铲子会更方便”一样有道理。

我知道这是一个很好的建议。但是我根本记不起我上次行凶的时候,同样我也记不起上次我需要使用这个通过一个变量就可以改变成任意尺寸的组件是什么时候。

所以这里我建议,开始一个项目之前先问问你自己:我需要写一个在某些情况下是固定大小,某些情况下又要放大10%的组件吗?如果答案是肯定的,那么就按着上面那篇博客教的做吧,那正是你需要的。

你可以用一个属性来缩放所以页面上的文本

(我决定标题上不加序号了)

另一个同样讨厌的叫你用em的原因是这样说的:假如你在css里50多个不同的地方都定义了font-size,然后希望所有50多个地方都在大屏上更大,小屏上更小,那你需要做超多媒体查询。

这种情况下明显最优解决方案是所有地方全用rem,然后媒体查询里直接改变根节点的字体大小,你就会震惊的发现,哇!所有字都变大了诶。

我觉得两点原因可以使这个提议被安全的忽略掉:

  1. 它假设你想在某个给定断点下放大缩小所有网页文本,包括标题,导航栏,正文,全部一次性而且是通过一个变量来进行缩放。这本身是件很需要勇气的事情。
  2. 主要问题是,如果你真的定义了font-size50多次,那么你更需要做的是好好组织一下你的排版了。

当你专门分出一个文件来定义排版,里面有12个样式,每个样式里你都有不同的尺寸去适应四种不同的屏幕大小,这样就有48个不同的font-size定义了,然后再加上line-height, margin, padding…就像丘吉尔说的,“这真是一个大工程”。

到那时你很容易的就会考虑到,“不行,重复的东西太多了,必须重构一下,不论代价如何决不能产生这么多的重复代码”。

其实我很不同意这个观点。我经常见到很多应用打着DRY(不要重复你自己)的名义引入了更多复杂的东西,永远不要低估混用不同单位时所增加的复杂性。NASA因为用了两套不同的单位现在都没能找到他们的火星轨道卫星。

别让你的网页也迷失在太空中了。

哦还不光是单位,还有那些以一个地方的字号为基准去改变另一个地方的字号的情况。这就是封装的对立面,它们瞧不起绝对确定的东西,而这样通常都只是自找麻烦。

所以还是好好地用px去写一下你的排版,稍微有点重复并不要紧,确保所有文本都是你指定的精确值,然后忘掉它,忙其他的去吧。

结论

所有以上这些可以总结成这一点:某些情况下因为某些特定原因你是应该使用rem或em,但这些场景正变得越来越少,也离那些建议原因越来越远。

所以不要再硬去寻找使用rem或em的理由了,px已经够用了。但如果你遇到了那些rem或em是更优选择的场景,那也放心去用吧。

关于单位使用的一些Bonus

下面的东西与本文无关,所以我只是简单列了下,并没有进一步阐述。

  • 如果你有两个相邻的文本位,且希望它们的padding差不多一个空格,那你可以试试1ch
  • 如果你希望body的背景色垂直方向至少占满一屏,那可以试试用100vh代替100%,但通常你要用vh的话,最好现在iOS设备上好好测试一下。
  • 你知道vertical-align可以用百分比吗?如果你发现vertical-align: supertop不是你想要的那样,别去加position: relative; top: -3px之类的代码,试试看vertical-align: 30%吧。
  • 当遇到弹性布局时,不要忘了flex-growflex-shrink,它们可能一开始会让你觉得有点头疼,但就像一个巨型棒棒糖一样,它们值得拥有。

原文:rems and ems, and why you probably don’t need them

作者:David Gilbertson

译者:Timi