转载

我所知道的所有的响应式网站排版

响应式排版是一个棘手的问题。下面这段代码是我一开始写响应式网站时所能想出来的最好的方法:

p {     font-size: 16px; }  @media (min-width: 800px) {     p {         font-size: 18px;     } }  /* Repeat for h1 - h6 and other type groups */

在那之后,我学习了更多的有关排版的问题,而且收集了一些非常棒的例子,比如使用相对单位,vertical rhythms和恰当的文本缩放排版。

这些新的例子都是非常棒的,它们让我的网站更加美观,更加赏心悦目。但是,实现这些功能的过程却是非常糟糕的。

我必须去写很复杂的代码,而且我发现在巨大的时间压力下,我挣扎于编写响应式网站中。

在几个月的辛苦工作之后,现在我终于找到了一个可以和各位分享的一个解决方法——Typi。

Typi是非常棒的,因为在三个简单的步骤之后,它不仅允许我去使用我曾经学过的例子,同时它还解决了大部分我所遇到的问题。现在,就让我通过我研究响应式排版时用过的例子,来向你具体解释一下这三个步骤。

当屏幕的大小增长时,增大字体大小和正文的行高。

移动端浏览网页和在PC端浏览网页是完全不同的体验。当你在一部屏幕比较小的移动端上浏览网页时,毫无疑问你会将设备靠近你自己。

和移动端相比,你的PC的屏幕会离你更远。因此,相同大小的字因为更远的距离的缘故在PC上显得略微小一点。

为了增加可读性,弥补由距离带来的字的大小上的视觉损失,我们增加了字体的大小。

我第一次接触这个例子是通过 ia.net 上的一篇文章———— Responsive Typography: The Basics 。如果你对我说的不是很了解,我强烈建议你去看看这篇文章。

下面贴出的代码是用Sass对这个例子的实现:

html {     font-size: 16px;      @media (min-width: 800px) {         font-size: 18px;     }      @media (min-width: 1200px) {         font-size: 20px;     } }

注:当我们增加字体的大小时,我们也可能需要去增加行高以满足每行文字间的空白。用Sass我们可以这么写:

html {     font-size: 16px;     line-height: 1.3;      @media (min-width: 800px) {         font-size: 18px;     }      @media (min-width: 1200px) {         font-size: 20px;         line-height: 1.4;     } }

为你的排版设置模块化文本缩放

为你的排版元素选择字体大小是很难的(从 <h1><h6> ),尤其是如果你想让它们更加的美观。一个模块化的文本缩放,或者说文本缩放排版是一个很好的工具,你可以用它来帮助你选择能够和空白部分完美契合的排版字体。

它们是一序列通过比例关联在一起的数字。它可以是你的文本字体大小乘上或除以一个比例来得到的。得到的数字之后再次乘上或者除以那个比例。

我所知道的所有的响应式网站排版

一个上图中模块化文本缩放的代码可以如下:

html { font-size: 16px } h1 { font-size: 50px } h2 { font-size: 37px } h3 { font-size: 28px } // ...

当然,事情没有这么简单。如果你记得之前我们讨论到的第一个例子,你可能会意识到正文的字体大小应该随着你的屏幕大小改变而改变。

当你必须为了保证缩放的一致性,从而去改变每个断点处你的所有元素的排版大小时,这个问题就会发生了,看下面的代码:

html {     font-size: 16px;     line-height: 1.3;      @media (min-width: 800px) {         font-size: 18px;     }      @media (min-width: 1200px) {         font-size: 20px;         line-height: 1.4;     } }  h1 {     font-size: 50px;      @media (min-width: 800px) {         font-size: 56px;     }      @media (min-width: 1200px) {         font-size: 63px;     } }  h2 {     font-size: 37px;      @media (min-width: 800px) {         font-size: 42px;     }      @media (min-width: 1200px) {         font-size: 47px;     } }  h2 {     font-size: 28px;      @media (min-width: 800px) {         font-size: 32px;     }      @media (min-width: 1200px) {         font-size: 35px;     } } // ...

想知道这个问题的答案的话可以看下一个例子。

注:如果你需要为你的模块化缩放选择开始的字体大小和缩放比例,我建议你读Tim Brown的一篇文章———— More Meaningful Typography 。

使用相对排版单位

在CSS中的相对单位有百分号( ),视窗单位( vhvmvminvmax ), em 单位( em )和 rem 单位( rem )。最常用的排版单位是 emrem

你可以同时在同一个行为中用 emrem 来解决我们在第二个例子中遇到的问题。为了将像素 px 转换成 em ,我们将 font-size 的值除以浏览器默认的基本字体大小(base-font size)。

看下面贴出来的代码:

html {     font-size: 16px;      @media (min-width: 800px) {         font-size: 18px;     }      @media (min-width: 1200px) {         font-size: 20px;     } }  h1 { font-size: 3.125em; } // 50 ÷ 16 = 3.125 h2 { font-size: 2.3125em;} // 37 ÷ 16 = 2.3125 h3 { font-size: 1.75em; } // 28 ÷ 16 = 1.75 // ...  // Note: These are approximate values. // The actual values derived from modularscale.com are 3.129em, 2.3353em and 1.769em respectively.

现在就好很多了!

这儿有一些问题需要我们注意。当屏幕宽度增加到 1200px 时, <h1> 的值变成大约 63px

63px 太大了。阅读标签 <h1> 内的文本已经不是很舒服了。一个更好的决定是将它的值调到 47px (也就是 <h2> 的大小)。

当这个情况发生的时候,你可能会想去降低标签 <h2> 的大小,因为标签 <h1> 可以很好的强调。有时候,你也可能需要去改变 line-height 的值。

所以代码现在就变成了这样:

html {     font-size: 16px;      @media (min-width: 800px) {         font-size: 18px;     }      @media (min-width: 1200px) {         font-size: 20px;     } }  h1 {     font-size: 3.129em;     line-height: 1.2;      @media (min-width: 1200px) {         font-size: 2.3353em;         line-height: 1.3;     } }  h2 {     font-size: 2.3353em;      @media (min-width: 1200px) {         font-size: 1.769em;     } }  h3 {     font-size: 1.769em;      @media (min-width: 1200px) {         font-size: 1.33em;     } }  // ...

额。。。现在我们回到出发点 :(

是时候来聊一聊Typi了,让我们先不管这些例子来看看Typi是怎么帮助你的吧。

使用Typi

Typi是一个Sass库,它可以允许你建立在分开的Sass map上所有排版元素的 font-sizeline-height 属性。这些map可以被用来输出我们下面解决方案中的代码。下面让我说说它是怎么工作的。

首先,你需要建立一个 $typi map,如下:

$typi: (     null: 16px,     small: 18px,     large: 20px );

null , smalllarge 是断点。

Typi自动的寻找一个 $breakpoints 图来建立你的媒体查询(意思就是将作者写的一个库 mappy-breakpoints 完美的整合在一起。)

$breakpoints: (     small: 800px,     large: 1200px );

一旦 $typi map被建立,我们在 html 选择器中调用 typi-base() 掺合模式。

html {     @include typi-base(); }

这个 typi-base() 掺合模式创建了和我们在例2中给 <html> 标签写的一样的样式。唯一的不同是 font-size 是用百分号表示。

html {     font-size: 100%; /* This means 16px */ }  @media all and (min-width: 800px) {     html {         font-size: 112.5%; /* This means 18px */     } }  @media all and (min-width: 1200px) {     html {         font-size: 125%; /* This means 20px */     } }

我们也提到当 font-size 的值改变时有可能需要改变 line-height 的值。你可以提前在Typi上通过给每个需要它的断点上提供一个第二 line-height 值来改变 line-height 的值。

$typi: (     null: (16px, 1.3), // Sets line-height to 1.3     small: 18px,     large: (20px, 1.4) // Sets line-height to 1.4 );

从我们更新的 $typi 图中我们可以得到CSS如下:

html {     font-size: 100%; /* This means 16px */     line-height: 1.3; }  @media all and (min-width: 800px) {     html {         font-size: 112.5%; /* This means 18px */     } }  @media all and (min-width: 1200px) {     html {         font-size: 125%; /* This means 20px */         line-height: 1.4;     } }

在创建 $typi 图后,我们可以用同样的格式来创建别的 font-maps ,下面是例子:

$h1-map: (     null: (3.129em, 1.2),     large: (2.3353em, 1.3) );  $h2-map: (     null: 2.3353em,     large: 1.769em );  $h3-map: (     null: 1.769em,     large: 1.333em ); // ...

之后,我们可以通过 typi 掺合模式来调用每一个font-maps

h1 { @include typi($h1-map) } h2 { @include typi($h2-map) } h3 { @include typi($h3-map) } // ...

最后得到的CSS如下:

h1 {     font-size: 3.129em;     line-height: 1.2; }  @media (min-width: 1200px) {     h1 {         font-size: 2.3353em;         line-height: 1.3;     } }  h2 {     font-size: 2.3353em; }  @media (min-width: 1200px) {     h2 {         font-size: 1.769em;     } }  h3 {     font-size: 1.769em; }  @media (min-width: 1200px) {     h3 {         font-size: 1.333em;     } }

非常的整齐是吧,你必须先去 下载Typi 来使用它(Sassmeister和Codepen上面还不能支持Typi)。

小技巧:

如果你不想在每个不同的字体map上写准确的 em 值(例如 1.769em ),你可以使用Sass mixin的模块化文本缩放。

如果你想这么做的话,你需要 下载库 并且把它导入到你的Sass文件中,之后你就可以用 ms() 函数来改变字体maps了。

$h1-map: (     null: (ms(4) 1.2),     large: (ms(3), 1.3) );  $h2-map: (     null: ms(3),     large: ms(2) );  $h3-map: (     null: ms(2),     large: ms(1) ); // ...

所以简而言之,Typi通过帮助你在不同断点上写 font-sizeline-height 属性来让响应式排版更容易。

现在我已经向你介绍了Typi,让我们回到之前的剩下的最后两个例子(一些问题我已经找到了解决方法)。

应用vertical rhythms

Vertical Rhythms在我看来是一个来自印刷设计的概念。在印刷设计中,我们需要保证一个页面中的元素的垂直距离与其他页面的一致性。这个想法与应用文本缩放的排版很类似————允许你的页面中的元素很好的浮动。

在实例中,我们经常用到 line-height 属性作为vertical rhythms一致性的基础。让我们把你的页面设置为 line-height = 25px ,你需要做下面的两件事情:

  • 把垂直元素之间的空白设置为 25px 的倍数。
  • 把每个文本元素的 line-height 设置为 25px 的倍数。

这是它看起来像CSS的地方(这儿还没有用到上面我们提到的三个实例)

html {     font-size: 18px;     line-height: 25px; }  // Resets margins body, h1, p {     margin: 0; }  h1 {     font-size: 63px;     line-height: 75px;     margin: 25px 0; }  p + p {     margin-top: 25px; }

这看起来非常的棒!让我们更进一步:将代码改成相对单位。当进行这一步时,你会遇到 emrem 的冲突。

Em vs Rem

让我们首先把代码转换成ems为单位,然后再转换成rems。顺便提一句, line-height 的值最好应该是没有单位的 。

html {     font-size: 1.125em;     line-height: 1.4; // This is 25.2px to be accurate }  // Resets margins body, h1, p {     margin: 0; }  h1 {     // font size is 63.147px to be more precise     font-size: 3.5082em; // 63.147 ÷ 18 = 3.5082em     line-height: 1.1972; // 75.6 ÷ 63.147 =  1.1972     margin: 0.3991em 0; // 25.2 ÷ 63.147 = 0.3991 }  p + p {     margin-top: 1.4em; }

特别要注意的是我们应该怎么把 <h1> 标签中的 margin 属性转换成ems。

要注意的是我们怎么用 63.147px 作为除数?这必须被解决因为以ems为单位的大小的计算需要依据当前的字体大小。它总会导致混乱并包含很多复杂的数学问题。

现在,这儿出现了一个问题。尽管我们尝试去做到更加的精确,但是浏览器似乎不和我们合作。你需要注意我们的vertical rhythms开始变得古怪。

两个问题导致了这个古怪的现象。

第一,我们没有百分之百的精确我们的数学计算。我们可以更加精确(比如精确到十位小数),但是这会让我们的代码像地狱一样丑陋。

第二,不同的浏览器处理子像素的舍入问题是不同的。这意味着不管我们怎么努力的去尝试,我们都不能获得最好的像素规律。

好了,我不想纠结于子像素的舍入问题,因为我们真的没有什么可以做的。现在,让我们转而看看 rem 是如何解决这个复杂的数学问题的,好吗?

html {     font-size: 1.125rem;     line-height: 1.4; // This is 25.2px to be accurate }  // Resets margins body, h1, p {     margin: 0; }  h1 {     font-size: 3.5082rem; // 63.147 ÷ 18 = 3.5082     line-height: 1.1972; // 75.6 ÷ 63.147 = 1.1972     margin: 1.4rem 0; // 25.2 ÷ 18 = 1.4 }  p + p {     margin-top: 1.4rem; }

请注意我们是如何用margin属性中的 1.4rem 来替代 1.3991em 的?Rem作为单位来进行vertical rhythms的计算会更佳简单。

这并不是说你必须不假思索的就将单位转换成 rem 单位。Rems和em都是很有用的,他们可以被用作不同的目的。我会在之后的某一天讨论这个话题。现在,让我们回到vertical rhythms。

现在,我们将vertical rhythms转换成相对单位,让我们看一看当我们将它与实例一结合起来的时候它是怎么运行的。( font-sizesline-heights 应该随着屏幕大小的改变而改变)。

我们可以用一个 media-query 来让这个例子尽可能的简单。我们也可以用 rem 单位。

html {     font-size: 1.125em;     line-height: 1.4;      @media (min-width: 1200px) {         font-size: 1.25em; // this is 20px         // Slight change in line heights at 1200px         line-height: 1.45 // this is 29px     } }  // Resets margins body, h1, p {     margin: 0; }  h1 {     font-size: 3.5082em;     line-height: 1.1972;     margin: 1.45rem 0;      @media (min-width: 1200px) {         // font-size is now 70.164px         line-height: 1.24; // 29px * 3 ÷ 70.164 = 1.24         margin: 1.45rem 0;     } }  p + p {     margin-top: 1.4em;      @media (min-width: 1200px) {         margin-top: 1.45em     } }

额。。。我们也许必须加 20000 个media queries来改变所有元素的 marginline-height 仅仅因为我们改变了 <html>line-height 的一个值。而且我们还没有讲 padding 属性和 border 属性呢!

所以,在这儿我明白了。在不同的浏览器之间实现完美的响应式vertical rhythms是不可能的。至少以现在的技术是不可能的。

那么,我们可以做那些事情来替代它呢?

  • 我们可以通过目测和使用Typi来设法解决主要的排版元素的 line-height 属性。
  • 如果可以的话不要去尝试改变你的 body 中的 line-height 属性。当 CSS的变量 最终支持所有的主流浏览器后,事情将会变的简单。

保持文本计量在45-75字符之间

当然,这个实例很简单。只需要记住:一个字符大约是 0.5em 。一个文本计量意思是你的文本的宽度必须在 22.5em37.5em 之间。

举个例子,在实际情况中,我主要会担心文本超出了 75 个字符。而如果你的文本没有到 45 个字符大小,那么你可能需要改变你的字体大小了。

article {     max-width: 30em;     /* Anywhere between 22.5em to 37.5em. Use your discretion */ }

总结

响应式排版很难。虽然现在还是没有完美的解决办法,但是我们可以尽我们最大的努力来解决它。

本文根据 @Zell 的《 Everything I know about Responsive Web Typography 》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处: http://zellwk.com/blog/responsive-typography/

我所知道的所有的响应式网站排版

飞鱼

常用昵称“飞鱼”,目前是武汉大学的学生,专业是软件工程。对HTML5,CSS,JavaScript等前端技术有浓厚的兴趣,希望在这儿能和大家分享自己的兴趣与爱好。

原文  http://www.w3cplus.com/responsive/responsive-typography.html
正文到此结束
Loading...