转载地址:http://www.denisdeng.com/?p=152
早些时候,我致力于一个 内容繁杂网站的重新设计。设计需求很简单:客户要求我们在保留组织已经存在的logo基础上,改善密密麻麻的字体以提高可阅读性,因此,在设计的初期,我花了大量时间为内容模板库准备一个良好的网格。
几年过去了,类似的思考很普遍,在 Mark Boulton, Khoi Vinh等人的提倡下,我们看到了网格排版热情的高涨,以及如何在网格中使用它。坦率地讲,这种观点红极一时,大量的 css 框架涌现出来,加上各种 工具的帮助,使得基于网格的设计更接近于每一个设计师,为什么不呢?经过几分钟的网格式思考之后,其优势逐渐明朗化:设计者对所组织的内容能获得一个合理、结构化得框架,用户能得到一个组织良好、可阅读的网站。
最小屏幕分辨率:无伤大雅的谎言
在探索弹性网页设计的好处时,我们依赖一个小小的谎言:“最小屏幕分辨率”。在我们所追求的一个又一个固定布局的后面,这七个字魔力无穷。或许每隔几年我们需要重访网站“增加”其宽度以防止其超出安全范围。“最小屏幕分辨率”使我们的设计针对一小部分用户,这些用户视我们的设计为神灵,就像PS中作出来的一样,他们总是在最大的1024*768的窗口中浏览,也就是说,他们从不使用 OLPC便携器,或者从不在已经过时四年的监视器上查看网页。如果用户没有遇到过“最小屏幕分辨率”的问题,那好,就让他们使用滚动条去吧!不是吗?
当然,我在写网站代码时,我并未对糟糕的固定宽度设计极尽谩骂之能事,而是留下一个清醒的事实:当我们设计出一个相当复杂的网格去满足客户内容需求时,客户以及客户端用户总是要求一个流动的布局。在我所列出的所有基于网格的设计中,几乎都是严格的固定宽度,这就产生了一个棘手的问题:如何构建流动网格?
事实证明,这很容易办到。
我真的要感谢IE浏览器吗?
面临难以克服的问题,我从我最拿手的开始以避免混淆,暂时将如何在一个非固定宽度布局中获得网格行为的问题搁置一旁,从我明白的开始:首先用color和background将其样式化,然后确定其类型。
你或许知道IE中像素字体调整的问题,或者更确切的说,它 完全阻止调整字体,设置一个段落的字体为16px的Georgion,无论用户如何增大或减小字体,它在IE下始终保持在16px。IE7以及后续的浏览器允许用户缩放整个页面,简单的调整像素字体在大部分IE浏览器中是禁止的。因此,为了给用户更大的空间,精明的设计师习惯抛弃像素字体,而是使用相对尺寸的字体,如关键字、百分比、或者我的最爱, ems。
如果你曾经使用过诸如em这样的相对单位,你一定了解上下文背景,换句话说,一个元素的实际em尺寸是相对于父元素的字体尺寸来计算的,例如,让我们从下面这个设计原型谈起:
使用像素字体的例子
没有一点花样:一些段落的字体为16px的Helvetica,无序列表的字体大小有轻微的减小,为14px,头部标题h1为24px,漂亮吗?
更美妙的是这样一个简单的规则获得了理想的效果。
body {
font: normal 100% Helvetica, Arial, sans-serif;
}
Font-size为“100%”,页面中所有元素的字体大小都相对浏览器(大多数情况下是16px)默认的大小定义。基于浏览器默认的样式,h1是较大的粗体,且很漂亮----但字体仍是Helvertica。因此,我们可以很容易的修改font-family去修复标题字体为Helvertica的问题。如何设置文本字体大小为24px?或者更精确地减小列表的字体大小?
借助于em很容易做到。用没一个元素的目标像素值除以其容器元素的字体大小,这样就可以获得理想的字体大小,或更为直截了当:
目标值 / 上下文 = 结果
如果假定body的字体大小为16px,就可以将每一个理想的字体大小带入到这个公式之中。为了匹配设计稿中标题的字体大小,我们用目标值24除以容器的16:
24 / 16 = 1.5
因此,标题的字体大小为body默认大小的1.5倍,我们可以将其写入到我们的样式单中:
h1 {
font-family: Georgia, serif;
font-size: 1.5em; /* 24px / 16px = 1.5em */
}
设置字体大小为14px的列表的em值时,用同样的公式。假设body的字体大小还是16px,之需要简单的相除即可:
14 / 16 = 0.875
这样得到0.875em,我们再次将其写入到我们的css之中。
ul {
font-size: 0.875em; /* 14px / 16px = 0.875em */
}
靠这两条规则,我们的示例页更接近于设计稿。经过 简单的清理之后,它将是完美的像素值,所有这些都是在公式(目标 / 上下文 = 结果)帮助下得到的。
在对客户的相对类型经过几个小时的清理之后,我认为我已经找到了答案,如果相对的字体大小是相对容器的比例,而不是像素,我们可以再网格中对不同的元素做相同的操作。
毕竟,它不是“黄金像素”
和先前一样,我从一个并不漂亮的简单布局开始:
很明显,我们的设计很简单。这些简单的样式交织着一个定义良好的网格:同样,7个124px宽的栏目,被24px宽的间隔分开,所有这些加起来的总和为988px。但是让我们忘掉那些糟糕的像素,比例才是新的黑马,对不?让我们从流动开始,baby。
开始之前,看看设计稿,固定还是流动。看看这个设计,评估不同的内容区域,谢天谢地,这是一个简单的库存单。
在最高水平上看,头部是title,内容区域跨越6栏,一些背景信息位于最左栏。从这个图可以看到,我们可以用一些关键字从语义和结构上充实我们的内容清单。
<div id="page">
<h1>The Ratio Revolution Will Not Be Televised</h1>
<div class="entry">
<h2>Anyone else tired of Helvetica?</h2>
<h3 class="info">A <a href="#">Blog</a> Entry:</h3>
<div class="content">
<div class="main">
<p>Main content goes here. Lorem ipsum etc., etc.</p>
</div><!-- /end .content -->
<div class="meta">
<p>Posted on etc., etc.</p>
</div><!-- /end .meta -->
</div><!-- /end .main -->
</div><!-- /end .entry -->
</div><!-- /end #page -->
应用一些简单的规则额,我们获得了一个不错起点。但是,#page容器并没有任何约束,因此,我们的内容将流动完全匹配浏览器窗口,让我们试着对大小进行控制。
#page {
margin: 40px auto;
padding: 0 1em;
max-width: 61.75em; /* 988px / 16px = 61.75em */
}
我们使用maring和padding使我们的设计透气些,在视窗和内容之间留下一点间隙。但是,在我们规则的最后一行,我们使用了字体公式的变种,确定了我们的设计的最大宽度。我们用设计稿的988除以16,这样用em设置最大宽度,其接近设计稿的像素宽度值,这样会阻止超过理想状态下的988px,既然我们是用em来设置上限,那么max-width的值会随着用户字体的增大而增大-----一记漂亮的小动作,如果使用一个小的css补丁,即使是在旧的IE中也能运行。
到此,我们的设计已得到妥善安排,让我们从设计清单的每一个元素开始。首先是页面的标题。在设计稿中,它跨越5个栏目,有4个间隔,总宽度为700px,它的左侧移去了一个栏目和一个间隔,留下了144px的偏移。如果是在固定宽度的是设计中,我们的工作就相当直接:
h1 {
margin-left: 144px;
width: 700px;
}
既然我们是在一个流动的背景下工作,固定尺寸就难以占上风。字体大小是相对尺寸,这提醒了我:网格中的方方面面以及排列的元素须用相对容器的比例来呈现。换句话说,在我们缩放字体的试验中,我们所见到的不仅仅是元素理想的大小,还包括容器中元素大小的关系,这使得我们将基于像素的设计转换成百分比,在页面缩放时保持网格完整的比例。
简言之,我们拥有了流动网格。
旧的不去,新的不来
从哪里开始?
目标值 / 上下文 = 结果
不错,这就是我们信赖的字体公式,我们可以用同样的比例分析将以像素为基础的宽度转换成以百分比为基础的弹性尺寸。因此,我们从700px宽的页面标题开始----它被988宽的容器包绕着。
结果是,我们只需要简单的用700除以988即可。
700 / 988 = 0.7085
0.7085转换成百分比为70.85%,其宽度可以直接写到我们的样式单中:
h1 {
width: 70.85%; /* 700px / 988px = 0.7085 */
}
对于144像素的margin可以作同样的处理吗?我总是喜欢诱导式发问:
144 / 988 = 0.14575
我们再次得到0.14575或14.575%,将margin-left的属性值直接增加到我们的样式单中:
h1 {
margin-left: 14.575%; /* 144px / 988px = 0.14575 */
width: 70.85%; /* 700px / 988px = 0.7085 */
}
通过测量标题相对于容器的margin和width,我们已经成功的将网格中的比例转换成了友好的百分比,即使是溢出以适应浏览器的窗口,标题的比例将保持完整。
我们可以用同样简单的分割包绕entry,设计稿上为844px,左边距为124px;
844 / 988 = 0.85425
对于information栏:
124 / 988 = 0.12551
将其转换成百分比,并写入到我们的样式单中,这样我们的布局会更加充实。
.entry h2,
.entry .content {
float: right;
width: 85.425%; /* 844px / 988px = 0.85425 */
}
.entry .info {
float: left;
width: 12.551%; /* 124px / 988px = 0.12551 */
}
添加了这些样式,我们的流动网格更加成形。
改变上下文
到此,我们已经获得较大的排序内容区域,单没有触及到内部区域。当前,博客的entry主要副本和它的相关信息占据entry的整个宽度,且在顶部相互堆叠。但是,在我们的原始设计稿中,博客中entry的主要副本跨越五栏,辅助信息位于最右边。
敏锐的读者会发现,在当前的设计中,entry主体的宽度于页面标题的宽度相同(700px),margin与我们先前已经定义的最左栏相同当我们使用以前计算好的尺寸时,我们不能使用同样的公式,因为上下文发生了改变。
既然我们是在一个新的容器中计算,我们就要用她的宽度作为上下文
与我们先前相对于988px的#page计算百分比不同,我们当前是在.entry .content中计算,显然它要小得多。很明显我们需要重新定义上下文,用.entry .content的宽度作为我么的参照点。因此,计算主要副本的百分比宽度时,其大小为700px,用它除以844。
700 / 844 = 0.82938
对于右边122px的一栏,我们用同样的参照点
124 / 844 = 0.14692
现在,将上面的尺寸写到我们的css中。
.entry .main {
float: left;
width: 82.938%; /* 700px / 844px = 0.82938 */
}
.entry .meta {
float: right;
width: 14.692%; /* 124px / 844px = 0.14692 */
}
到此为止,我们完成了我们的工作,我们的流动网格完成。
四舍五入的问题
因为缺乏css补丁,你可能猜想,这种技巧有一些跨浏览器问题。我向你隆重推荐John Resig的关于css中的亚像素的优秀文章,它解释了不同浏览器是如何处理百分比宽度的,以及调和亚像素问题。正如John Resig在他的文章中解释的一样,现代浏览器在50px宽的容器中呈现四个25%宽的元素时,不能实际渲染至12.5px;大多数将向上或向下计算以更好地适应布局,不幸的是,IE将向上计算所有的亚像素尺寸,从而破坏了布局。
如果你在网格中留下足够的边距,问题就不会出现。但是,如果在IE中基于百分比的栏造成了不必要的包绕,将目标像素值降低一个像素将很管用。例如,在IE中左侧marg太宽,,你可以作如下改变:
124 / 988 = 0.12551
将124px降低至123px;
123 / 988 = 0.12449
将12.449的宽度放到针对IE的特定样式单中,问题就会迎刃而解。
网格无处不在
当然,上面所说只是一个起点,流动网页设计面临着重大挑战。当你介绍固定内容(如image、flash等)进入流动框架时,大部分设计师就已经出现。在我的blog中我已经尝试了一些可能的方法。
最后,我不敢说布局很简单,无论是固定还是流动。鉴于我们在过去几年里取得的成绩----移去表格、在公司和我们的同行中间大力宣传标准,这要求我们的浏览器更好的标准化。我希望我和我的同行们能充分发挥聪明才智去打破对“最小屏幕分辩率”的依赖,毕竟,我们用户的浏览习惯并不局限在我们的设计图上。我希望流动网格会释放你的想象力,我也很高兴地看到你如何改进该项技术,我们的用户也能做到。
补充阅读
或许我有点自相矛盾。我有两个鼓舞人心的理念是:一个是流动网格设计,一个是最近考虑成熟的网格的重要性,所有这些都受到下面的启发,虽然这不是一份完整的清单:
- John Allsopp, A Dao of Web Design
- Mark Boulton, Feeling your way around grids
- David Emery, More Width
- Molly Holzschlag, Thinking Outside the Grid
- Jeremy Keith, The unpushed envelope
- Jeffrey Zeldman, Rules-based design
最后,在去年八月结束此次谈话之后,有人提到流动960网格系统.。如果你使用的是诸如960 网格系统的公共css框架,流动端口可能会激起你的兴趣。