天天看点

《响应式Web设计实践》一2.2 字体大小

本节书摘来异步社区《响应式web设计实践》一书中的第2章,第2.2节,作者: 【美】tim kadlec 译者: 侯鸿儒 责编: 赵轩,更多章节内容可以访问云栖社区“异步社区”公众号查看。

响应式web设计实践

要想让你的设计拥抱web的流动性,那就意味着在你的设计中要能够灵活地改变字体大小。你可以在web上使用任意单位来设置字体大小,但主要的方法不外乎三种:像素、em,还有百分比。

长期以来,像素一直都是人们喜欢使用的字体大小单位,其原因很简单:无论浏览器如何设置字体大小,你都能对其进行精确的控制。如果你把字体设置为18px,那么每个浏览器都会将其准确地显示为18px。

但这样的掌控是要付出一定代价的。对于初学者而言,虽然使用像素作为字体大小单位时不需要考虑级联——父元素的字体大小对子元素没有影响,但这也意味着当你想让某些文本以不同的大小显示时就需要对它们逐一设置。这对于维护来说非常不利,因为当你想增大所有字体时,你就不得不去逐一修改每一个值。

更重要的是,以像素为单位的字体存在着潜在的可访问性问题。所有主流的浏览器都允许用户放大或缩小页面,浏览器对该操作通常有两种实现方式。

第一种方式是简单地将页面上所有的东西都放大,所以当访问者放大页面时,包括文本在内的所有的元素都会变大。在这种情况下,无论字体大小使用哪种单位,都允许用户进行缩放(图2.2)。

另外一种方式是浏览器只调整文本的大小,页面上其他元素则保持不变。长期以来这都是常见的浏览器实现方式,并且现在仍有一些浏览器采用这种方式实现缩放功能。

而且不幸的是,以像素为单位的字体在老版本的ie中是无法实现缩放的。这意味着那些使用ie9之前的、字体被设为默认大小的ie浏览器(或者在最新版中启用了字体默认大小的浏览器)的用户,是不能调节你的页面中字体的大小的。

《响应式Web设计实践》一2.2 字体大小

无法调整字体大小的问题也同样出现在很多较老的、在触摸屏出现之前就已经存在的设备上。有时所有的页面内容都不能缩放,在这种情况下,虽然字体还是同样的大小,但部分页面也许就不太适合人们阅读了。

浏览器能够调整文本的能力给了用户更多的控制权,另外作为浏览器本来就应该实现的功能,这样做也可以提高站点的可访问性。因为对于某些访问者来说,当字体大小小于某一数值时,就会给他们的阅读造成障碍。所以允许用户增大字体就意味着他们可以继续享用你的站点里的内容。

用像素指定字体大小依然不是一种对未来特别友好的方式。由于不同的设备有着不同的屏幕大小和像素密度,因此以像素为单位的字体也许在这台设备上看起来不错,但在另外一台设备上看起来也许就会要么太大、要么太小了(本章后面“默认字体大小”对此会做进一步的讨论)。使用像素作为字体大小的单位,是与web的灵活性原则背道而驰的做法。

使用em作为字体大小的单位是一种更加流行、更具灵活性的方法 。正如前面介绍过的那样,1em等于默认的字体大小,例如,如果内容的字体大小是16px,那么:

em可以跨浏览器进行缩放,而且它们也是级联的——这既可以是好事,也可以是坏事。从简化维护的角度来看这是好事,因为这样相对地指定元素的字体大小,意味着你只需要调整初始化时的基准,其余部分就会自动地进行调整,而且是按比例调整的。

但级联也会使事情变得复杂。例如,考虑一下下面的html:

其对应的css如下:

在上面的例子中,字体基准被设置为了16px,h1元素的字体大小为1.5em,即24px。我们想把span元素的字体大小设置为16px,所以我们将其设置为1em。但问题在于上下文环境变了:基准已经不再是body字体的16px了,而是h1元素的24px。因此span元素的字体大小将会显示为24px,而不是我们期望的16px。

所以我们需要调整span元素的font-size来缩小它:

要试着结构化你的css和html,并保持字体大小的可预测性。例如,如果你的内容部分使用了基准字体大小,并且只改变了标题元素的大小,那么你就可以避免这些问题了。类似地,如果你的html是经过精心设计的,你也可以很容易地通过后代选择器来解决这些问题。

后代选择器 一种css选择器,用来匹配特定元素的子元素。

和以em为单位的字体一样,以百分比为单位的字体也是可缩放的,而且也是级联的。另外与em类似的是,如果基准字体大小是16px的话,那么100%相当于16px,200%相当于32px。

虽然从理论上讲,百分比和em没有太大的区别,而且em逐渐成为了web中更受欢迎的字体度量单位,但其实这其中并没有什么技术上的原因。只有当出于em直接与文本大小相关的考虑时,使用em才更有意义。

然而,承蒙众多用户喜爱的ie浏览器,却在显示以em为单位的基准字体时会有问题。如果基准字体是以em为单位的,那么ie会夸大实际应当调整的字体大小。假如你把基准字体大小设置为了1em,并且把h1元素的设置为了2em,在绝大多数的浏览器中,h1元素会像我们预料的那样显示:它们会变大两倍,但在ie中它们会变得更大。要解决这个问题,我们得感谢下面这个小小的漏洞。

你可以通过在body元素上以百分比为单位指定基准字体大小来绕过这个问题。

引人注目的是,在大多数浏览器和设备中,默认的字体大小都是16px(后面专栏中有更多的相关信息)。通过将body的字体设置为100%,你就可以保证页面内容是可缩放的了,而且不会有夸大的现象,之后你就又可以使用em来指定其他元素的字体大小了。

默认字体大小 我们已经知道在桌面浏览器中,默认的页面字体大小是16px,所以当你把页面的font-size指定为100%时,你就能在不同的浏览器中得到相同大小的字体了。 但这一特性对于其他类型的设备来说有时就不那么奏效了。例如,当我在一台运行着黑莓6.0操作系统的黑莓手机上测试时,默认的font-size是22px,而kindle touch上的结果则更具戏剧性:它的初始默认大小是26px。 在你开始朝它们扔东西之前,请先听听它们这样做的原因。很多这样的新设备都有着较高的分辨率,因此16px的字体在上面看起来会非常小。大多数设备只好通过向浏览器报告说,自己有一个与实际不符的分辨率来绕过这个问题。例如,iphone 4的分辨率为640x960,但是它会告诉浏览器自己的分辨率是320x480。 其他诸如kindle touch这样的设备,会向浏览器报告真实的分辨率,但会通过增大默认的font-size来进行补偿。 其实最重要的不是屏幕实际的像素大小,屏幕上文字的可读性才是真正重要的。虽然可以将基准的font-size设置为100%,但要记住用户使用的设备的基准字体大小也许不是16px(这是一个在媒介查询中使用em的好例子,我们将会在下一章讨论这方面的内容)。

2.2.4 奖励关卡:rem

还有另外一种极具潜力,并兼具灵活性的设置字体大小的方法:以rem(“root em”)作为单位。rem与em的区别在于:rem的大小与根元素——html元素——有关。

使用rem能够避免发生在嵌套元素中的级联问题,让我们更新一下css,并以rem为单位来样式化列表项:

在上面这个例子中,h1元素的字体大小依然为24px,但是span元素将会显示为16px,因为在使用root em作为单位之后,span元素将继承html元素的字体大小,而不是包含它的div元素。

但对于rem,这里有一处有关移动浏览器支持情况的告诫。通常情况下,rem在桌面电脑浏览器中都能得到很好的支持:ie9+、firefox 3.6+、chrome 6.0+、safari 5.0+以及opera 11.6+都支持rem。另外,ios 4.0+和android 2.1+也可以提供相应的支持。但不幸的是,在写这本书时其他移动平台(包括流行的opera mobile)还都不支持rem。

为了应对上面这些情况,你可以额外设置一个以像素为单位的备用方案。

使用上面这种方法,支持rem的浏览器将会使用rem声明,因为它是在后面声明的,而那些不支持rem的浏览器将会使用第一条使用像素的声明,并忽略rem声明。

提示

在决定要采用哪种方式时,这里有一些权衡利弊时需要考虑的因素。使用em不但可以使文字能够缩放,而且维护起来也更加容易。例如,如果你要将整个站点的字体都增大,那么只需简单地修改body上字体的百分比即可。如果使用rem,由于需要有像素声明作为补充,所以你还要更新所有的像素值。

在本书后面的内容当中,我们将以百分比来作为body元素字体大小的单位,而以em来作为其他元素的单位。

你手中的每一个项目在刚开始时都新鲜无比,这当然很好,因为它们允许你从一开始就使用流动的设计。但事实是这样的可能性不大,因为大多数项目都会涉及迁移,此时你要能够将原有的固定大小的元素或者单位转换为一些更加灵活的东西。

鉴于此,让我们先来看一段完全以像素为单位的代码片段(图2.3)。

《响应式Web设计实践》一2.2 字体大小

在这段代码中,body的字体大小为16px,h1元素的字体大小为24px,span元素的字体大小为12px。

将上面这段代码转换为更具灵活性的代码相对来说比较容易。我们首先来设置body的字体大小:

你需要记住的是,这里设置100%对于大多数浏览器来说能保证基准font-size的值为16px,此外这样做也为我们提供了一个灵活的基准,让我们能在其之上进行其他设计。

通过一个简单的数学方程式我们就能将剩下的内容轻易地转换为em了。“我知道,我知道”——如果你想做数学题,那最好还是去买本算术书吧。不过谢天谢地,你不必知道圆周率的平方根的余弦值就可以算出这里的em值了,因为方程式很简单:

以h1元素为例,对于h1元素而言,我们的目标是24px,上下文环境等于容器元素的font-size值——在这里是body的16px。所以我们用24除以16,结果是1.5em:

注意声明后面的注释。作为一个在回顾我前一天写的代码(更不用说一个月前写的代码)时都会经常挠头的人,我强烈建议你使用注释,它们可以帮你回忆起这些数值是怎么来的。

我们可以将相同的方程式应用到span元素上。因为span元素位于h1元素内,所以上下文环境也改变了:现在是h1元素。经过计算,我们将span的font-size设置为.5em(12/24)。

更新后的代码如下所示:

灵活地指定字体大小——现在你已经实现它了!现在即使你更改了body的字体大小,body的字体大小与标题元素字体大小之间的比例也不会改变(图2.4)。

《响应式Web设计实践》一2.2 字体大小

指定大小的字体完全相同,但现在当字体增大时,其比例将保持不变。

继续阅读