CSS得到一个不好的名声,比较难懂, 一方面由于浏览器的不兼容,另一方面由于网上大量的技巧,每个CSS作者都可以有自己的方法去创建多列布局, 新的CSS开发者只是使用一种方法而不去理解其原理。这样的情况由于CSS框架的出现而变得更加严重,其通过创建标记和样式化表现的耦合来达到简化的目的, 这正是表格布局一开始被抛弃的原因, 这种黑箱实现的CSS也许可以快速得到结果,却最终阻碍开发者理解CSS的语言和作用去实现变化。
所有的CSS布局技巧依靠三个基本概念,positioning, floating, and margin manipulation, 不通过的技巧真的很不同, 如果你理解核心概念, 这就很容易创建你自己的布局,事实上, 布局是CSS最容易的部分,调整才需要耗时间。
这个章节,你将学习:
• Horizontally centering a design on a page
• Creating two- and three-column float-based layouts
• Creating fixed-width, liquid, and elastic layouts
• Creating equal height columns
• CSS frameworks versus CSS systems
当你把设计转化成能工作的模板, 直接开始制作页面和切图是很吸引人的, 但是你会发现很快就被逼入死角, 相反, 一点规划的工作可以拯救很多将来的麻烦。 就像老话说的:测量两次,裁剪一下。
创建可扩展和以维护的CSS系统的第一步是审查设计,找出重复的模式, 这些可以使页面中结构的模式, 或者某个元素在整个站点重复出现的方式。 你不可以过于关注视觉表现, 相反着重在结构和意义。 这时我喜欢做的是打印出整个设计, 发现模式然后草稿出每页的mark-up记录, 我也见过人们标注他们的Photoshop文档, 或灰盒子设计。
开始把你的页面分割出主要的结构区域,譬如: 容器wrapper, 页头header, 内容content area, 页脚footer。 这些区域整个站一致, 很少改变。 用一个建筑学的比喻, 你可以把它们想象成建筑的外墙。
然后,把注意力集中到内容区 content area, 开始创建出格子结构(grid structure)有多少不同的内容区呢?它们不同之处?内容区是否真的不同, 或者从布局角度来看可被看做同一种形式?大部分设计只有几个独立的内容区,找它们共享的特征而不是视觉表现。可以想象它们是建筑的承重墙。
最后,你需要开始看一下不同的内容区里面的不同的布局构造, 你是否需要2列,3列还是4列去呈现? 不同之前的步骤, 这些布局构造比较灵活而且每页不同, 你可以想象它们像分隔墙, 这几个步骤从底层帮你规划了页面, 现在拿出纸张和彩笔, 开始画结构图的细节尺寸。
结构准备好,你就开始转到不同种类的内容上。 这是新闻故事,文章,还是新闻简报。 每个框给一个有意义的名字。 看他们之间的关系, 可能最后发现,新闻故事和新闻简报差别很少, 这样把他们组合成一个内容类型可能更合理。
通过观察每个内容块如何构造, 寻找不同构造类型之间的模式。 例如,如果注意到文章和新闻故事都有个显眼的标题标题和脚注, 那么把他们鉴别出来。标题和脚注看起来不同没有关系, 你可以根据上下文去样式化。 错误信息,查询框, 菜单项都是照此处理, 保持class名称尽量一般化, 然后根据上下文来样式化它们。
一旦模式和命名规范整理好, 就可以定义将要使用的元素,例如一个无序列表代表一串链接, 一个故事可以使一个div 和h2, 一个paragraph, 和一个anchor元素, 预先和几个同事一起做比匆匆忙忙做简单些。 一开始记录好颜色代码, 尺寸和其他会有帮助, 你也可以记录在设计的打印稿上来快速参考。
设置基础
我们先看看设计一个三列的博客模板,
By analyzing the design, it’s clear that we’re going to need a wrapper element to center the
design, along with a header, content area, and footer. The markup would, therefore, look
something like this:分析设计之后, 很清楚我们需要一个容器元素使之居中, 然后添加一个header, content area, 和footer, markup会如下所示:
<body>
<div class=”wrapper”>
<div class=”header”>
<!—Your header content goes here –>
</div>
<div class=”content”>
<!—Your page content goes here –>
</div>
<div class=”footer”>
<!—Your footer content goes here—>
</div>
</div>
</body>
至少三个区域要在容器内, 那么就可以开始样式化容器。
用Margin来置中
长文本难以阅读,现在显示器尺寸不断变大, 屏幕的可读性越来越重要。 解决方法之一就是让设计居中,居中的设计只占据屏幕一部分,而不是占据整个屏幕, 这样就创建比较短且容易阅读的行。
比如说你有个布局,希望将div容器居中于屏幕
<body>
<div class="wrapper">
</div>
</body>要做到这点,只要定义div的width属性,并且设置水平margin为auto:
.wrapper{
width:920px;
margin:0 auto;
}
这个例子中,我决定将div容器中的宽度固定为920 pixels, 所以其在1024x768解析度的屏幕是很合适的,但是,你也可以设置宽度为body的百分比, 或比例与text的尺寸而使用em。
这在所有现代浏览器中有效, 但是在IE5.X和IE6 兼容模式不支持margin:auto声明, 幸运的是,IE会误认为text-align:center, 让所有东西居中, 而不只是文本。 你可以使用这种方法是所有东西居中, 包括容器div, 然后重新把容器内容左对齐。
body{
text-align:center;
}
.wrapper{
width: 920px;
margin: 0 auto;
text-align: left;
}
使用text-align属性来居中是一个hack,但是并没有害处, 对站点没有不良影响, 容器现在IE和其他符合标准的浏览器都会居中。
使用CSS居中有不同的方式, 包括绝对定位和负值margin, 发现基于浮动的布局是最容易使用的方法,顾名思义,在基于浮动的布局中, 只需要设置希望定位的元素的宽度, 然后将它们向左或向右浮动。
因为浮动的元素不再占据文档流的空间, 它们就不再对包围它们的框块产生影响, 为了解决这个问题,需要对布局中各个点上的浮动元素进行清理,非常常见的做法是, 不对元素进行连续的浮动和清理,而是浮动几乎所有东西,然后再整个文档的“战略点”,比如页脚上进行一次或两次清理。
两列浮动布局
<div class="content">
<div class="primary">
<!-- main content goes here –>
</div>
<div class="secondary”>
<!--navigation and secondary content goes here –>
</div>
</div>
整个设计的第二内容区,包括导航,会靠近页面的左边, 主内容区靠页面右边, 但是代码顺序,我选择把主内容区放在第二内容区之上,首先主内容区对于页面最重要,第二方便屏幕阅读器用户。
创建基于浮动的布局,一般将两列都向左浮动,然后使用margin或padding 在两列之间创建一个隔离带。 使用这样的方法,列的可用空间可以包得很紧,没有喘息的空间, 如果浏览器表现良好的话, 这不是问题,可是差劲的浏览器会打乱紧密的布局,迫使一列走到另一列下面。
在IE上会发生这种情况, 因为IE考虑元素的内容尺寸, 而不是元素本身尺寸。在符合标准的浏览器中,如果元素内容太大, 它只会超出框之外, 但是如果在IE上,如果元素内容过大, 整个元素会扩张, 这个可以因为小事而引发, 比如文字设置为Italic。如果这发生在紧密的布局中,那么就没有足够空间可以让元素并排出现,浮动元素之一就会走下面去, 其他IE bug, 像3像素文本偏移bug和双空白边浮动bug,也会导致浮动元素下降。
要放置布局被打破, 需要避免塞太多浮动布局元素到它的容器中, 与其使用水平margin 或 padding来创建分离带, 你可以用一个元素向左浮动,一个元素向右浮动来创建一个隔离带, 如果一个元素尺寸意外增加了几个pixel, 那么它只会填入隔离带,而不是马上耗尽水平空间向下降。
实现这个布局很直观, 你只需设置每个列想要的宽度,然后将次要内容左浮动,主要内容右浮动,你可能需要加一点padding到主内容放置它里面的文字紧贴盒子的右边缘, 你注意到我为每个浮动元素添加了display:inline,这是个预防措施,防止IE里面double margin 浮动bug,下面章节会讲到。
.content .primary {
width: 650px;
padding-right: 20px;
float: right;
display: inline;
}
.content .secondary {
width: 230px;
float: left;
display: inline;
}
因为总宽度是920像素, 所以两个浮动元素之间留出20像素的隔离带, 前面提过,这样做可以防止因内容膨胀而出现浮动元素下降。
因为这些元素浮动后,不占用文档流的空间, 导致footer上升,要防止它,你需要对浮动元素的父元素(这个例子是content)添加overflow:hidden来实现。
.content {
overflow: hidden;
}And there you have it: a simple two-column CSS layout
You’ll notice that rather than creating two separate elements called primary-content and
secondary-content, I’ve simply used the terms primary and secondary. I’ve then used the fact
that these two elements are nested within the content element to create the association. This has
a couple of benefits. First off, it means that you don’t have to keep creating new class names for
every element you want to style. Instead, you can use the cascade to help you out. Secondly, and
arguably more importantly, you can use the same primary and secondary classes more than
once, creating a very flexible naming system. For instance, say we wanted to create a threecolumn
layout instead of just a two-column one.
三列浮动布局