本节书摘来异步社区《响应式Web设计实践》一书中的第2章,第2.3节,作者: 【美】Tim Kadlec 译者: 侯鸿儒 责编: 赵轩,更多章节内容可以访问云栖社区“异步社区”公众号查看。
2.3 网格布局
响应式Web设计实践
早在Web出现前的数十年,在设计中使用网格就已经是一种异常流行的做法了,因为网格有助于实现站点的平衡、间距以及组织结构。一个实现良好的网格系统会使你的站点井井有条,同时还可以提高页面的可读性和可浏览性。
注意
关于网格的更多信息,可以参阅Khoi Vinh的书籍,或者找一份Mark Boulton的系列视频来看。
在《“Ordering Disorder: Grid Principles for Web Design”(秩序之美:网页中的网格设计)》一书中,作者Khoi Vinh便强调了使用网格进行设计的四大主要优势。当你把这些优势同时运用在设计中时,你会看到它们之间更为紧密的联系。
网格使信息的展示变得有序、新颖、和谐。
网格使得用户能够预测该从哪里获得信息,这在信息交流过程中很有帮助。
在与原始总体设想相一致的前提下,网格使添加新的内容更为容易。
网格能在设计单一解决方案时促进合作,而不必对总体设想的解决方案妥协。
框架简述
在网上可以找到大量基于网格的框架,这些框架模板和CSS规则能帮你快速搭建出预先定义好的网格布局。在这些框架中,有些是灵活的,而有些则不是,它们中的大多数都介于12列至16列之间。虽然在每个新项目中都使用你最喜爱的框架是一件诱人的事,但其实我们可以做得比这更有创意。
虽然使用12列的网格并没有什么不妥,但是如果在每个站点中都使用12列的网格就会产生让人感到厌烦、可预测的布局。为了能够从网格布局那里获得最大的益处,你得针对每个项目重新考虑一下框架。
大胆地去合并那些列,并实现一个3列或者5列的网格吧!那些设计得最为漂亮的Web站点,没有一个会使用被人们用烂了的12列布局的——有时越简单越好。
2.3.1 从内容出发
使用网格布局要做的第一件事就是确定画布。在图形设计中,画布就是你的纸,它的大小决定了网格。你得先把画布划分为若干你需要的列(3列、5列、9列,甚至12列),然后才能继续后面的工作。
正如我们之前讨论过的,在Web上没有像在纸上那样准确的尺寸,你得工作在内容之外,并让内容来决定网格。
为了清楚起见,这里需要说明的一点是,当我说“内容”的时候,我并不是特指文本,我说的内容有很多种形式:广告、视频、图片、文本。这些不同类型的内容都可以决定你的网格。例如,如果你的公司是一家出版公司,并且收入主要来自于广告,那么比较明智的做法是围绕IAB的一两个特定的广告大小来确定你的网格。同样,如果你正在重新设计一个有很多遗留图片的大型网站,那么你就要根据这些图片来确定你的网格。
让你的内容来决定你站点的结构是一种很好的设计方法,而且这样做也是非常实用的。相比把遗留的图片或者广告硬塞进一个事先就定义好的网格中,不如从一开始就让你的网格来配合它们,这会让每个页面的设计都更具粘性。
已经唠叨得够多了,下面让我们来动手写一些代码吧。
2.3.2 设置网格
让我们从一个虚构的体育刊物——《另一个体育网站》(原创的,这我知道)开始吧。我们将为文章页面设计一个网格,默认的颜色和字体样式已经写好了(出于示例的考虑,我们要等到下一章才会引入页面的header和footer)。让我们先来看一下需要处理的内容:
1. <body id="top">
2. <div id="container">
3. <article class="main" role="main">
4. <h1>That guy has the ball</h1>
5. <p class="summary">In what has to be considered a
development of the utmost importance, that man over
there now has the ball.</p>
6. <p class="articleInfo">By Ricky Boucher |
<time>January 1, 2012</time></p>
7. <section>
8. <img src="images/football.jpg" alt="Football" />
9. <p>...</p>
10. </section>
11. </article>
12. <aside>
13. <section class="related">
14. <h2>Related Headlines</h2>
15. <ul>
16. <li>
17. <a href="#">That Guy Knocked Out the Other
Guy</a>
18. </li>
19. ...
20. </ul>
21. </section>
22. <section class="ad">
23. <img src="images/ad.png" alt="Boombox ad unit" />
24. </section>
25. <section class="article-tags">
26. <h2>Tagged</h2>
27. <ul class="tags">
28. <li><a href="#">Football</a></li>
29. ...
30. </ul>
31. </section>
32. <section class="soundbites">
33. <h2>Sound Bites</h2>
34. <blockquote>
35. ..this much is clear to me. If I were in his
shoes, I would have already won 5
Super Bowls.
36. <cite><a href="#">—Guy with big
ego</a></cite>
37. </blockquote>
38. </section>
39. </aside>
40. <div class="more-stories">
41. <h2>More in Football</h2>
42. <ul class="slats">
43. <li class="group">
44. <a href="#">
45. <img src="images/ball.jpg"
alt="Look, it's a ball!" />
46. <h3>Kicker connects on record 13 field
goals</h3>
47. </a>
48. </li>
49. ...
50. </ul>
51. </div>
52. </div><!-- /#container -->
53. </body>
提示
可以访问http://implementingrespon-sivedesign.com/ex/ch2/ch2-start.html来查看实际效果。
我们是水平最高的开发者,所以对于要在页面上显示什么内容我们早已成竹在胸,而且还为我们的设计创建了牢固的HTML结构。在我们的页面中会包括一篇文章,每篇文章又会包括一个用h1元素表示的大标题、作者名字以及一则概述,之后便是放在section元素内的文章正文部分了。
每个文章页面还会有一个边栏,里面包含一个最近文章标题的无序列表。由于《另一个体育网站》如果不通过广告来收费的话,那么它还需要去寻找别的赚钱途径,因此每个文章页面还需要有一个300px × 250px的广告空间。这是我们遇到的第一个限制,我们可以根据该限制来设计网格。
提示
可以在https://github.com/robbiemanson/960px-Grid-Templates查看Robbie Manson在Github上的代码仓库,里面有可以在Photoshop和Fireworks中使用的各式各样的模板。
最后,边栏中还需要有一个与文章相关的标签列表,并引用一些他人的言论。其中标签以无序列表的形式展示,而引用则要放在blockquote元素当中。
让我们先来用一种古老而传统的方法来创建我们的网格——以像素为单位。
960px,让我们尝试使用9列网格来取代经常使用的12列网格。9列网格的每一列都为84px宽,而且它们之间还有24px的间隔,共计948px。一个300px宽的广告可以很容易地放到网格的最后3列当中去,剩下的6列则留给文章内容使用。
首先,我们来设置容器元素的宽度:
#container{
width: 948px;
}
然后让文章和边栏分别向左、右浮动,并为它们指定适当的宽度:
aside {
float: right;
width: 300px;
}
.main {
float: left;
width: 624px;
}
到此为止,布局看起来已经相当可爱了。网格让设计中的元素看起来是有联系的,而且文章的宽度也非常利于阅读,这会使用户的阅读过程非常轻松。
提示
可以访问http://imp-lementingrespon-sivedesign. com/ex/ch2/ch2.2.html来查看实际效果。
但是,当你缩小浏览器窗口时,问题便会马上暴露:当浏览器宽度小于948px的时候,我们又看到了讨厌的水平滚动条,屏幕中又不能同时显示所有的内容了(图2.5)。
虽然我们已经设计出了一个不错的网格,但它目前还只适用于一小部分用户使用,下面让我们来做一些弥补吧,好吗?
让网格变得灵活
如果此时你想起了前面让字体变灵活的方法,那么其实你可以把同样的方程式(目标/上下文=结果)应用在灵活化网格布局上来。
容器的上下文是948px,在这样的容器里实现流动布局是件很容易的事:
aside {
float: right;
width: 31.6455696%; /* 300/948 */
}
.main {
float: left;
width: 65.8227848%; /* 624/948 */
}
Box-sizing
如果你看过上面这个页面的样式表,那么也许你会注意到下面这3行代码几乎应用到了所有元素上:
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
CSS中默认的盒模型会让人觉得有问题:你本来已经定义好了width,但你之后定义的所有padding又都会被算到这个width中去。例如,如果你创建了一个300px宽的列,之后在其左右各加了20px宽的padding,那么此时该列的宽度就会变成340px。 这在人们创建基于网格的流动布局时,会使人感到相当痛苦。
通过使用box-sizing: border-box,你就可以让浏览器将padding的值算在已经定义好的元素宽度内部了。通过使用这一属性,一个300px宽的列即使两边新增了20px的padding,它的宽度依然会是300px,因为padding的宽度被算在了元素内部。这使得设计流动布局变得更加容易。
在不使用box-sizing的情况下(如右图所示),一个宽为300px且有20px padding的元素,其宽和高都会变为340px 。而在使用了box-sizing后,元素仍然是300px宽、300px高。
在包含了box-sizing的各种版本的前缀之后,这一属性就可以获得很好的浏览器支持了。在桌面及移动设备的主流浏览器中,只有IE8之前的IE浏览器对此缺乏支持。实际上,大多数浏览器对此已经支持了很长一段时间了,比如Chrome和Firefox,从第一个版本开始就支持前缀语法了。
最后,我们来让页面中的其他部分也流动起来。
.main {
float: left;
margin-right: 2.5316456%; /* 24px / 948px */
width: 31.6455696%; /* 300/948 */
}
注意
为什么是95%?其实没有什么确切的原因。我试了几种不同的宽度,结果95%在不同的浏览器宽度下都显示得非常好。有时候,设计中真的就是靠看和感觉来定的。
现在,内容栏和边栏都实现了流动布局,下面我们要将容器上现有的固定宽度也去掉。我们将页面容器的总宽度设置为95%来取代之前的948px,留一点padding(译者注:指剩下的那5%)能给页面一些呼吸的空间:
#container{
width: 95%;
padding: .625em 1.0548523% 1.5em; /* 10px/16px, 10px/948,
24px/16px */
margin: auto 0;
}
在这个例子中,我们使用em作为顶部和底部padding的单位,并使用百分比作为左右两边padding的单位,之所以要这样做是由上下文所决定的。因为顶部和底部的padding值是由font-size的大小决定的,所以使用em更有意义。
流动世界中的固定宽度对象
下一个要讨论的对象就是图片。当你缩放浏览器窗口时,有着固定宽度的图片就会变得极为醒目,因为与周围其他流动的内容相比,它们会显得格格不入。在较宽的列中它们只会占据一小部分;而在较窄的列中它们又太宽。不过谢天谢地,让它们变整齐也是很容易的。
我们要做的第一件事,就是使用下面的声明来让图片填满整个边栏:
aside img,
.main img,
.slats img {
width: 100%;
}
这里需要注意的很重要的一点是,不能在HTML中设定img元素的height和width的属性值,因为如果设定了这些值,就不能按比例缩放图片了。为了使流动图片正常工作,你只能通过CSS来控制图片的大小。
然后我们需要声明max-width。通过将max-width设置为100%,我们便可以告诉浏览器不要让图片的大小超过了它的容器元素(本例中是边栏)。这样,即使浏览器窗口变窄,图片也不会溢出或被裁剪了:
aside img,
.main img,
.slats img {
width: 100%;
max-width: 100%;
}
至此,我们便拥有了一个流动布局——能够自适应地调整自己,而且在大部分的设备上都是可用的(图2.6)。在提升有关图片的体验方面我们还有很多事可以做,我们将在第4章中再对此做详细介绍。
提示
可以访问http://implementingrespon-sivedesign.com/ex/ch2/ch2.3.html 来查看实际效果。