第二章 可视化格式模型

 

要掌握的三个最重要的CSS概念是浮动、定位和框模型。这些概念控制在页面上安排和显示元素的方式,形成CSS的基本布局。如果你习惯于用表格控制布局,那么这些概念初看上去可能有点儿奇怪。实际上,大多数人只有在使用CSS开发站点一段时间之后,才能完全掌握框模型的复杂性、绝对定位和相对定位之间的差异以及浮动和清理的实际工作方式。在切实掌握这些概念之后,使用CSS开发站点就会变得容易多了。

在本章中,你将学习:

  • 框模型的复杂性和特性。
  • 如何以及为什么使用空白边叠加。
  • 绝对定位和相对定位之间的差异。
  • 浮动和清理是如何工作的。

2.1 框模型概述

框模型是CSS的基石之一,它指定元素如何显示以及(在某种程度上)如何相互交互。页面上的每个元素被看做一个矩形框,这个框由元素的内容、填充、边框和空白边组成(见图2-1)。
填充出现在内容区域的周围。如果在元素上添加背景,那么背景会应用于由内容和填充组成的区域。因此,常常使用填充在内容周围创建一个隔离带,使内容不会与背景混在一起。添加边框会在填充的区域外边加一条线。这些线可以有多种样式,比如实线、虚线或点线。在边框外边是空白边。空白边是透明的。一般使用它控制元素之间的间隔。

填充、边框和空白边都是可选的,默认值为零。但是,许多元素将由用户代理样式设置空白边和填充。可以通过将元素的 margin 或 padding 设置为零来覆盖这些浏览器样式。这可以分别进行,也可以使用通用选择器对所有元素进行设置:
* {
margin: 0;
padding: 0;
}
在CSS中,width 和 height 指的是内容区域的宽度和高度。增加填充、边框和空白边不会影响内容区域的尺寸,但是会增加元素框的总尺寸。假设框的每个边上有 10 像素的空白边和 5 像素的填充,如果如果希望这个框达到 100 像素宽,就需要将内容的宽度设置为 70 像素 (见图 2-2):

#myBox {

margin: 10px;

padding: 5px;

width: 70px;

}

填充、边框和空白边可以应用于一个元素的所有边,也可以应用于单独的边。空白边还可以是负值,并且在多种技术中都要使用负值的空白边。

2.1.1 IE/Win 和框模型

不幸的是,IE 5.x 和 IE 6 在怪异模式中使用自己的非标准框模型。这些浏览器的 width 属性不是内容的宽度,而是内容、填充和边框的宽度总和。这实际上有一定的意义,因为在现实世界中框具有固定的尺寸,而且填充是放在框里面的。添加的填充越多,给内容留下的空间就越少。尽管符合逻辑,但是这些 IE 版本不符合规范,这会造成严重的问题。例如,在前面的示例中,在 IE 5.x 中框的总宽度只有 90 像素。这是因为 IE 5.x 认为 每个边上 5 像素的填充是 70 像素的宽度的一部分,而不是在宽度之外附加的 (见图 2-3)。

幸运的是,有几个方法快可以解决这个问题,这些方法的细节可以在第 9 章中找到。但是,目前最好的解决方案是回避这个问题。也就是,不要给元素添加具有指定宽度的填充,而是尝试将填充或空白边添加到元素的父元素或子元素。

2.1.2 空白边叠加

空白边叠加是一个相当简单的概念。但是,在实践中对网页进行布局时,它会造成许多混淆。简单地说,当两个垂直空白边相遇时,它们将形成一个空白边。这个空白边的高度等于两个发生叠加的空白边的高度中的较大者。

当一个元素出现在另一个元素上面时,第一个元素的底空白边与第二个元素的顶空白边发生叠加 (见图 2-4)。

当一个元素包含在另一个元素中时候 (假设没有填充或边框将空白边分隔开),它们的顶和/或底空白边也发生叠加 (见图 2-5)。
尽管初看上去有点儿奇怪,但是空白边甚至可以与本身发生叠加。假设有一个空元素,它有空白边,但是没有边框或填充。在这种情况下,顶空白边与底空白边就碰到了一起,它们会发生叠加  (见图 2-6) 。
如果这个空白边碰到另一个元素的空白边,它还会发生叠加  (见图 2-7)。

这就是一系列空的段落元素占用的空间非常小的原因,因为它们的所有空白边都叠加到一起,形成一个小的空白边。

空白边叠加初看上去可能有点儿奇怪,但是它实际上是有意义的。以由几个段落组成的典型文本页面为例 (见图 2-8)。第一个段落上面的空间等于段落的顶空白边。如果没有空白边叠加,后续所有段落之间的空白边将是相邻顶空白边和底空白边的和。这意味着段落之间的空间是页面顶部的两倍。如果发生空白边叠加,段落之间的顶空白边和底空白边叠加在一起,这样各处的距离就一致了。

*****只有普通文档流中块框的垂直空白边才会发生空白边叠加。行内框浮动框绝对定位框之间的空白边不会叠加。*****

2.2 定位概述

既然已经熟悉了框模型,我们就来看看视觉格式化模型定位模型。理解这两个模型的细微差异是非常重要的,因为它们一起控制着如何在页面上布置每个元素。

2.2.1 视觉格式化模型

p、h1 或 div 等元素常常称为块级元素。这意味着这些元素显示为一块内容,即 "块框"。与之相反,strong 和 span 等元素称为行内元素,因为它们的内容显示在行中,即 "行内框"。

可以使用 display 属性改变生成的框的类型。这意味着,通过将 display 属性设置为 block,可以让行内元素 (比如锚) 表现得像块级元素一样。还可以通过将 display 属性设置为 none ,让生成的元素根本没有框。这样,这个框及其所有内容就不显示,不占用文档中的空间。

****CSS 中有三种基本的定位机制:普通流、浮动和绝对定位。****

除非专门指定,否则所有框都在普通流中定位。顾名思义,普通流中元素框的位置由元素在 (X)HTML 中的位置决定。

块级框从上到下一个接一个地排列;框之间的垂直距离由框的垂直空白边计算出来。

行内框在一行中水平布置。****可以使用水平填充、边框和空白边调整它们的水平间距 (见图2-9) 。但是,垂直填充、边框和空白边不影响行内框的高度。****由一行形成的水平框称为行框****行框的高度总是足以容纳它包含的所有行内框。但是,设置行高可以增加这个框的高度。****

框可以按照 (X)HTML 元素的嵌套方式包含其他框。大多数框由显示定义的元素形成。 但是,在一种情况下,即使没有进行显示定义,也会创建块级元素。这种情况发生在将一些文本添加到一个块级元素 (比如 div) 的开头时。即使没有把这些文本定义为段落,它也会被当作段落对待:

在这种情况下,这个框称为无名块框,因为它不与专门定义的元素相关联。

块级元素内的文本行也会发生类似的情况。假设有一个包含三行文本的段落。每行文本形成一个无名行框。无法直接对无名块或行框应用样式,因为没有可以应用样式的地方。但是,这有助于理解在屏幕上看到的所有东西都形成某种框。

2.2.2 相对定位

相对定位是一个非常容易掌握的概念。如果对一个元素进行相对定位,它将出现在它所在的位置上。然后,可以通过设置垂直或水平位置,让这个元素 "相对于" 它的起点进行移动。如果 top 设置为 20 像素,那么框将出现在原位置顶部下面 20 像素的地方。如果将 left 设置为 20 像素,那么会在元素左边创建 20 像素的空间,也就是将元素向右移动 (见图 2-10) 。

在使用相对定位时,无论是否进行移动,元素仍然占据原来的空间。因此,移动元素会导致它覆盖其他框。

2.2.3 绝对定位

相对定位实际上被看作普通流定位模型的一部分,因为元素的位置相对于它在普通流中的位置。与之相反,绝对定位使元素的位置与文档流无关,因为不占据空间。普通文档流中其他元素的布局就像绝对定位的元素不存在时一样 (见图 2-11) 。

绝对定位的元素的位置相对于最近的已定位祖先元素。如果元素没有已定位的祖先元素,那么它的位置相对于最初的包含块。根据用户代理的不同,最初的包含块可能是画布或HTML 元素。

与相对定位的框一样,绝对定位的框可以从它的包含块向上、下、左、右移动。这提供了很大的灵活性。可以直接将元素定位在页面上的任何位置。

对于定位的主要问题是要记住每种定位的意义。相对定位是 "相对于" 元素在文档流中的初始位置,而绝对定位是 "相对于" 最近的已定位祖先元素,如果不存在已定位的祖先元素,那么是最初的包含块。

因为绝对定位的框与文档流无关,所以它们可以覆盖页面上的其他元素。可以通过设置 z-index 属性来控制这些框的堆放次序。z-index 值越高,框在堆中的位置就越高。

绝对定位的元素的位置相对于最近的已定位祖先元素,这使我们能够实现一些非常有意思的效果。例如,假如希望让一个文本段落对准一个大框的右下角。只需对包含框进行相对定位,然后相对于这个框对段落进行绝对定位:

#branding {

width: 700px;

height: 100px;

position: relative;

}

#branding .tel {

position: absolute;

right: 10px;

bottom: 10px;

text-align: right;

}

<div id="branding">

<p class="tel">Tel: 0845 838 6163</p>

</div>

相对于相对定位的祖先元素对框进行绝对定位,这在大多数现代浏览器中实现得很好。

*****但是,在 Windows 上的 IE5.5 和 IE6 中有一个 bug。如果试图相对于相对定位的框的右边或底部设置绝对定位的框的位置,那么需要确保相对定位的框已经设置了尺寸。如果没有,那么 IE 会相对于画布定位这个框。****

在第9章可以进一步了解这个 bug 和修复方法。简单的解决方案是为相对定位的框设置宽度和高度,从而避免这一问题。

在进行页面布局时,绝对定位是非常有用的工具,尤其是在使用相对定位的祖先元素的情况下。完全可能只使用绝对定位创建出整个设计。为此,这些元素需要具有固定尺寸,这样就能够将它们定位在任何地方而不会有重叠的风险。

因为绝对定位的元素与文档流无关,所以它们不影响普通流中的框。如果扩大绝对定位的框 (例如,通过增加字号),周围的框不会重新定位。因此,尺寸的任何改变会导致绝对定位的框产生重叠,从而破坏精心调整过的布局。

固定定位

固定定位是绝对定位的一个子类别。差别在于固定元素的包含块是视口。这使我们能够创建总是出现在窗口中相同位置的浮动元素。这种情况的一个示例可以在 snook.ca 上看到 (见图 2-12)。博客评论表单采用固定定位,这使它在页面滚动时一直出现在屏幕上的相同位置。这有助于改进易用性,用户不必为了发表评论而一直滚动到页面底部。

不幸的是,IE6和更低版本不支持固定定位。为了解决这个问题,Jonathan Snook 使用 JavaScript 在 IE 中重现了这个效果。

2.2.4 浮动

最后一种定位模型是浮动模型。浮动的框可以左右移动,直到它的外边缘碰到包含框或另一个浮动框的边缘

****因为浮动框不在文档的普通流中,所以文档的普通流中的块框表现得就像浮动框不存在一样。****

如图 2-13 所示,当把框 1 向右浮动时,它脱离文档流并且向右移动,直到它的右边缘碰到包含框的右边缘。

在图 2-14 中, 当把框 1 向左浮动时,它脱离文档流并且向左移动,直到它的左边缘碰到包含框的左边缘。因为它不再处于文档流中,所以它不占据空间,实际上覆盖住了框2,使框2从试图中消失。如果把所有三个框都向左浮动,那么框 1向左浮动直到碰到包含框,另外两个框向左浮动直到碰到前一个浮动框。
如果包含块太窄,无法容纳水平排列的三个浮动元素,那么其他浮动块向下移动,直到有足够的空间的地方 (见图 2-15)。如果浮动元素的高度不同,那么当它们向下移动时可能会被其他浮动元素 "卡住" 。

行框和清理
浮动框旁边的行框被缩短,从而给浮动框留出空间,行框围绕浮动框。 实际上,创建浮动框使文本可以围绕图像 (见图2-16)。

要想阻止行框围绕在浮动框的外边,需要对这个框应用 clear 。clear 属性的值可以是 left、right、both 或 none,它表示框的哪些边不应该挨着浮动框。为了实现这种效果,在被清理元素的顶空白边上添加足够的空间,使元素的顶边缘垂直下降到浮动框下面 (见图 2-17) 。

****浮动元素脱离了文档流,不影响周围的元素。但是,对元素进行清理实际上为前面的浮动元素留出了垂直空间。****
这是一个有用的布局工具,它让周围的元素为浮动元素留出空间。这解决了前面看到的绝对定位的问题,也就是垂直高度的改变不影响周围的元素,从而破坏了设计。
我们来更详细地看看浮动和清理。假设有一个图片,希望让它浮动到一个文本块的左边。希望将这个图片和文本包含在另一个具有背景颜色和边框的元素中。你可能会编写下面这样的代码:
.news {
background-color: gray;
border: solid 1px black;
}
.news img {
float: left;
}
.news p {
float: right;
}
<div class="news">
<img src="news-pic.jpg" />
<p>Some text</p>
</div>
但是, 因为浮动元素脱离了文档流,所以包围图片和文本的 div 不占据空间。如何让包围元素在视觉上包围浮动元素呢?需要在这个元素中的某个地方应用 clear (见图 2-18)。

不幸的是,没有现有的元素可以应用清理,所以需要添加一个空元素并且清理它。
.news {
background-color: gray;
border: 1px solid black;
}
.news img {
float: left;
}
.news p {
float: right;
}
.clear {
clear: both;
}
<div class="news">
<img src="news-pic.jpg" />
<p>Some text</p>
<div class="clear"></div>
</div>
这会实现我们希望的效果,但是要添加不必要的代码。常常有元素可以应用 clear,但是有时候不得不为了进行布局而添加无意义的标记。
还可以不对浮动的文本和图像进行清理,而是选择对容器 div 进行浮动:
.news {
background-color: gray;
border: solid 1px black;
float: left;
}
.news img {
float: left;
}
.news p {
float: right;
}
<div class="news">
<img src="news-pic.jpg" />
<p>Some text</p>
</div>
这也会产生我们想要的结果。不幸的是,下一个元素会受到这个浮动元素的影响。为了解决这个问题,有些人选择对布局中的几乎所有东西进行浮动,然后使用适当的有意义 (常常是站点的页脚) 对这些浮动元素进行清理。这有助于减少或消除不必要的标记。但是,浮动会变得复杂,而且一些老式浏览器在处理有许多浮动元素的布局时有困难。因此,许多人喜欢添加少量的额外标记。
应用值为 hidden 或 auto 的 overflow 属性会自动地清理包含的任何浮动元素,而不需要添加额外的标记。这个方法并不适合所有情况,因为设置框的 overflow 属性会影响它的表现。
最后,一些人使用 CSS 生成的内容或 JavaScript 对浮动元素进行清理。这两种方法的基本概念是相同的。并不直接向标记中添加进行清理的元素,而是将它们动态地添加到页面中。对于这两种方法,需要指定进行清理的元素出现在哪里,而且常常需要添加一个类名:
<div class="news clear">
<img src="news-pic.jpg" />
<p>Some text</p>
</div>
在使用 CSS 方法时,结合使用 :after 伪类和内容声明在指定的现有内容的末尾添加新的内容。 在这个示例中,我添加了一个句点,因为它是个非常小的不引人注意的字符。不希望新的内容占据垂直空间或者在页面上显示,所以需要将 height 设置为 0,将 visibility 设置为 hidden 。因为被清理的元素在它们的顶空白边上添加了空间,所以生成的内容需要将它的 display 属性设置为 block 。
这样设置之后,就可以对生成的内容进行清理:
.clear:after {
content: ".";
height: 0;
visibility: hidden;
display: block;
clear: both;
}
这个方法在大多数现代浏览器中是有效的,但是在 IE6 和更低版本中不起作用。有各种解决方案,其中许多记录在 www.positioniseverything.net/easyclearing.html 中。 最常用的解决方案涉及使用 Holly 招数 (见第8章),从而迫使 IE5-6应用 "布局" (见第9章) 和不正确地清理浮动元素。
.clear {
display: inline-block;
}
/* Holly Hack Targets IE Win only */
* html .clear { height: 1%; }
.clear {display: block;}
/* End Holly Hack */
但是,由于其复杂性,这个方法可能不适合所有人采用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值