精通 CSS - 高级 Web 标准解决方案 8. 布局
所有 CSS 布局技术的根本都是 3 个基本概念:定位、浮动和外边距操纵。
8.1 计划布局
布局时先做一些计划可以避免很多问题。
- 先把页面规划为大的结构性区域,比如容器、页眉、内容区域和页脚。
- 然后,将注意力转移到内容区域本身,开始建立网格结构。
- 最后,在各个内容区域中寻找不同的布局结构。
结构设计完之后,可以开始关注不同类型的内容。
查看每个内容块的结构,看看不同的类型中是否有共同的模式。
找出模式并确定命名规约之后,最好马上开始定义将使用的元素。
8.2 设置基本结构
典型的三列博客模板。
<body>
<div class="wrapper">
<div class="header">
<!-- Your header content goes here -->
</div>
<div class="content">
<!-- Your content content goes here -->
</div>
<div class="footer">
<!-- Your footer content goes here -->
</div>
</div>
</body>
使用外边距让设计居中
设置主体 div
的宽度,并将水平外边距设置为 auto 。
.wrapper {
width: 920px;
margin: 0 auto;
}
8.3 基于浮动的布局
基于浮动的布局是最容易使用的,也是最可靠的。只需设置希望定位的元素的宽度,然后将它们向左或向右浮动。
因为浮动的元素不再占据文档流中的任何空间,它们就不再对包围它们的块框产生任何影响。为了解决这个问题,需要对布局中各个点上的浮动元素进行清理。非常常见的做法是浮动几乎所有东西,然后在整个文档的“战略点”(比如页脚)上进行一次或两次清理。还可以使用溢出方法清理某些元素的内容。
8.3.1 两列的浮动布局
<div class="content">
<div class="primary">
<!-- main content goes here -->
</div>
<div class="secondary">
<!-- navigation and secondary content goes here -->
</div>
</div>
为每个列设置想要的宽度,然后将次要内容向左浮动,将主要内容向右浮动。
/* 将主要内容向右浮动 */
.content .primary {
width: 650px;
padding-right: 20px;
float: right;
display: inline;
}
/* 将次要内容向左浮动 */
.content .secondary {
width: 230px;
float: left;
display: inline;
}
/* 清除浮动 */
.content {
overflow: hidden;
}
8.3.2 三列的浮动布局
和两列布局唯一的差异是在内容 div 中添加了两个新的 div:一个用于主内容,一个用于次要内容。
<div class="content">
<div class="primary">
<div class="primary">
<!-- primary primary content goes here -->
</div>
<div class="secondary">
<!-- secondary primary content goes here -->
</div>
</div>
<div class="secondary">
<!-- navigation and secondary content goes here -->
</div>
</div>
.content .primary .primary {
width: 400px;
float: left;
display: inline;
}
.content .prmary .secondary {
width: 230px;
float: right;
display: inline;
}
8.4 固定宽度、流式和弹性布局
上面的两个布局都是固定宽度的布局。该布局比较常见,因为开发人员可以精确的定位元素的位置。
但缺陷也很明显,因为尺寸是固定的,导致无法适配各种分辨率的屏幕。另外更改浏览器的文本字号时可能会导致页面不易阅读。
8.4.1 流式布局
尺寸使用百分比而不是像素来设置。
问题:在窗口较窄时,行会变的非常窄。窗口太大时,也会导致行太宽,也同样不适合阅读。
/* 以整个页面宽度为基准计算出百分比 */
.wrapper {
width: 76.8%;
margin: 0 auto;
text-align: left;
/* 为了确保窗口过大或过小时页面文本也适合阅读,最好以 em 为单位设置最大和最小宽度 */
max-width: 125em;
min-width: 62em;
}
.content .primary {
width: 72.82%;
float: right;
display: inline;
}
.content .secondary {
width: 25%;
float: left;
display: inline;
}
/* 以主要内容的宽度为基准计算百分比 */
.content .primary .primary {
width: 59.7%;
float: left;
display: inline;
}
.content .primary .secondary {
width: 34.33%;
padding-right: 2.63%;
float: right;
display: inline;
}
8.4.2 弹性布局
弹性布局相对于字号(而不是浏览器宽度)来设置元素的宽度。以 em
为单位设置宽度。
问题:不能充分利用可用空间。另外字号增大时整个布局会加大,进而导致水平滚动条出现。需要在容器 div
上设置 max-width 。
将固定宽度布局转换为弹性布局是相对简单的任务。技巧是要设置基字号,让 1em 大致相当于 10px 。
大多数浏览器上的默认字号是 16px,10px 大约是 16px 的 62.5%,所以在主题上将字号设置为 62.5% 。
body {
font-size: 62.5%;
text-align: center;
}
.wrapper {
width: 92em;
max-width: 95%;
margin: 0 auto;
text-align: left;
}
/* 内部宽度仍然使用百分比 */
.content .primary {
width: 72.82%;
float: right;
display: inline;
}
.content .secondary {
width: 25%;
float: left;
display: inline;
}
.content .primary .primary {
width: 59.7%;
float: left;
display: inline;
}
.content .primary .secondary {
width: 34.33%;
padding-right: 2em;
float: right;
display: inline;
}
现代浏览器很多都已支持页面缩放了。
8.4.3 流式和弹性图像
使用流式或单行布局,固定宽度的图像会对设计产生强烈的影响。
对于需要跨越大区域的图像,比如站点页眉或品牌区域中的图像,可以考虑率使用背景图像而不是图片元素。
#branding {
height: 171px;
background: url(/img/branding.png) no-repeat left top;
}
<div id="branding"></div>
如果图像需要用作页面上的图像元素,需要将宽度设置为 100% 并且将 overflow
设置为 hidden。
#branding {
width: 100%;
overflow: hidden;
}
<div id="branding">
<img src="/img/branding" width="1600" height="171" />
</div>
对于常规内容图片,你可能希望它们可以水平和垂直伸缩。
.news img {
/* 设置图片的宽度为百分比,这样就可以实现自动伸缩 */
width: 25%;
/* 设置最大宽度,以避免图像失真 */
max-width: 200px;
float: left;
display: inline;
padding: 2%;
}
.news p {
width: 68%;
float: right;
display: inline;
padding: 2% 2% 2% 0;
}
8.5 faux 列
每个区域由于内部元素的高度各不相同,会导致背景色没有渲染到整列。
对策是在一个占据布局最大高度的元素(比如一个容器 div)上应用重复的背景图像。
#wrapper {
background: #fff url(/img/nav-bg-fixwd.gif) repeat-y left top;
}
对于流式或弹性布局时,则需要多张背景图片分别按照百分比进行定位。
.wrapper {
background: #fff url(/img/secondary-faux-column.gif) repeat-y 25% 0;
}
.inner-wrapper {
background: #fff url(/img/primary-faux-column.gif) repeat-y 72.82% 0;
}
8.6 高度相等的列
使用表格很容易实现这种效果,但是 CSS 中实现需要一点技巧。
<div class="wrapper">
<div class="box">
<p>狩魔猎人</p>
<p>...</p>
<div class="bottom"></div>
</div>
<div class="box">
<p>秘术师</p>
<p>...</p>
<div class="bottom"></div>
</div>
<div class="box">
<p>圣教军</p>
<p>...</p>
<div class="bottom"></div>
</div>
</div>
.wrapper {
width: 100%;
}
.box {
width: 250px;
margin-left: 20px;
float: left;
display: inline;
padding: 20px;
background: #89ac10 url(/img/top.gif) no-repeat left top;
}
这会产生 3 个高度不一致的列。
这种技术的关键是给每个框设置大的底内边距,然后用数值相似的负外边距消除这个高度。
.wrapper {
width: 100%;
overflow: hidden;
}
.box {
width: 250px;
padding-left: 20px;
padding-right: 20px;
padding-top: 20px;
padding-bottom: 520px;
margin-bottom: -500px;
margin-left: 20px;
floatL left;
display: inline;
background: #89ac10 url(/img/top.gif) no-repeat left top;
}
为了把列的底边定位在正确的位置,需要让它们与容器元素的底部对齐。
为此,首先把容器的 position
设置为 relative。然后把 bottom 的 position
设置为 absolute,把它们的 bottom 属性设置为 0。
.wrapper {
width: 100%;
overflow: hidden;
position: relative;
}
.bottom {
position: absolute;
bottom: 0;
height: 20px;
width: 290px;
background: url(/img/bottom.gif) #89ac10 bottom left no-repeat;
margin-left: -20px;
}
8.7 CSS 3 列
CSS 3 也可以创建等高文本列,这要通过 column-count
、 column-width
和 column-gap
属性实现。
<p>狩魔猎人</p>
<div class="col">
<p>...</p>
</div>
.col {
-moz-column-count: 3;
-moz-column-width: 14em;
-moz-column-gap: 2em;
-moz-column-rule: 1px solid #ccc;
-webkit-column-count: 3;
-webkit-column-width: 14em;
-webkit-column-gap: 2em;
-webkit-column-rule: 1px solid #ccc;
column-count: 3;
column-width: 14em;
column-gap: 2em;
column-rule: 1px solid #ccc;
}
8.8 CSS 框架与 CSS 系统
CSS 框架 的目标是简化 CSS 的使用,帮助用户方便地创建各种常用的布局,而不需要编辑底层的 CSS。如 YUI Griids、Blueprint 和 960 等。
但其也有缺点,会改变编写标记的方式,破坏变现和意义的分离;要求在设计中必须使用特定的网格结构。
CSS 系统 实际上是一个工具箱,其中包含可重用的样式和标记模式,可以用它开发站点专用的框架。
工具箱可以包含全局 reset、排版样式和表单处理,以及登录表单、日历表格和导航列表等常用 HTML 组件的标记模式。然后再开发作为定制框架使用的系统。
附 1. 引用
- 《精通 CSS - 高级 Web 标准解决方案(第 2 版)》 - Andy Budd, Simon Collison, Cameron Moll 著;陈剑瓯 译。
本书后面还有 3 章,分别讲了 bug 的发现与修复方法 和 两个作者写的示例及其用到的一些未来可能会实装的 CSS 特性(由于这本书买的比较早,现在看来常用的浏览器都已经支持这些新的特性了)。
这里就不再继续写了。有兴趣的同学可以买书看一下。
9. bug 和 修复 bug
10. 实例研究:Roma Italia
11. 实例研究:Climb the Mountains