Skip to content

精通 CSS - 高级 Web 标准解决方案 3. 可视化格式模型

🏷️ 《精通 CSS - 高级 Web 标准解决方案》

你需要掌握的 3 个最重要的 CSS 概念是 浮动定位盒模型

3.1. 盒模型概述

盒模型是 CSS 的基石之一,它指定元素如何显示以及(在某种程度上)如何相互交互。
页面上的每个元素都可以看做一个矩形框,这个框由元素的内容内边距边框外边距组成。

内边距(padding)出现在内容区域(content)的周围。背景会应用于内容和内边距组成的区域。
添加边框(border)会在内边距的区域外添加一条线(可以是实线、虚线或点线)。
外边距(margin)是透明的,一般用于控制元素之间的间隔。
CSS 2.1 还包含 outline 属性。轮廓绘制在元素框之上,不影响元素的大小和定位。轮廓有助于修复 bug,因为它不影响页面的布局。IE 8 及以上支持。

内边距、边框和边框都是可选的,默认值为零。

在 CSS 中,widthheigth 指的是内容区域的宽度和高度。增加内边距、边框和外边距不会影响内容区域的尺寸,但是会增加元素框的总尺寸。

内边距、边框和外边距可以应用一个元素的所有变,也可以应用于单独的边。外边距还可以是负值。

外边距叠加

当两个或更多垂直外边距相遇时,它们将形成一个外边距。这个外边距的高度等于两个发生叠加的外边距的高度中的较大者。
外边距甚至可以与本身发生叠加(没有边框和内边距的空元素,本身的顶外边距和底外边距会叠加)。
只有普通文档流中块框的垂直外边距才会发生外边距叠加。行内框、浮动框和绝对定位框之间的外边距不会叠加。

3.2. 定位概述

可视化格式模型

ph1div 等元素常常称为 块级元素
strongspan 等元素称为 行内元素

可以使用 display 属性改变生成的框的类型。
dispaly: block; 可以让行内元素变得像块级元素一样;
dispaly: inline-block; 可以让元素像行内元素一样水平地依次排列;
display: none; 可以让生成的元素根本没有框,所有内容都不再显示,也不占用文档中的空间。

CSS 中有 3 中基本的定位机制:普通流浮动绝对定位

匿名块框:一个块级元素开头的文本,即使没有把这些文本定义为块级元素,它也会被当做块级元素对待。

html
<div>
    some text
    <p>Some more text</p>
</div>

相对定位

如果对一个元素进行相对定位,它将出现在它所在的位置上。然后,可以通过设置垂直或水平位置,让这个元素“相对于”它的起点移动。

css
#myBox {
    position: relative;
    left: 20px;
    top: 20px;
}

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

绝对定位

相对定位实际上被看做普通流定位模型中的一部分,因为元素的位置是相对于它在普通流中的位置的。
与之相反,绝对定位使元素的位置与文档流无关,因此不占据空间。

绝对定位的元素的位置是相对于距离它最近的那个已定位的祖先元素确定的。
如果元素没有已定位的祖先元素,那么它的位置是相对于初始包含块的。

可以通过设置 z-index 属性来控制这些框的叠放次序。 z-index 的值越高,框在栈中的位置就越高。

css
#branding .tel {
    position: absolute;
    right: 1em;
    bottom: 1em;
    text-align: right;
}

固定定位

固定定位是绝对定位的一种。差异在于固定元素的包含块是视口(viewport
这使我们能够创建总是出现在窗口中相同位置的浮动元素。

css
.fixed {
    position: fixed;
}

浮动

浮动的框可以左右移动,直到它的外边缘碰到包含框或另一个浮动框的边缘。浮动框不在文档的普通流中。

向右浮动时,脱离文档流并向右移动,直到它的右边缘碰到包含框的右边缘;
向左浮动时,脱离文档流并向左移动,直到它的左边缘碰到包含框的左边缘;
如果多个框都向左浮动,那么第一个框向左浮动直到碰到包含框,后面的框向左浮动直到碰到前一个浮动框;
如果包含框太窄,那么浮动框向下浮动,直到有足够的空间;
如果浮动元素的高度不同,那么当它们向下移动时可能会被其它浮动元素“卡住”;

css
.float {
    float: right;
}

行框和清理

浮动会让元素脱离文档流,但是浮动元素后面的文档流中的文本内容会受到影响,文本内容会移动以留出空间。
浮动元素旁边的行框会被缩短,从而给浮动元素留出空间,因此行框会围绕浮动框。

要想阻止行框围绕浮动框,需要对包含这些行框的元素应用 clear 属性。clear 属性可以是 leftrightbothnone,它表示框的哪些边不应该挨着浮动框。
在清理元素时,浏览器在元素顶上添加足够的外边距,使元素的顶边缘垂直下降到浮动框的下面。

浮动元素脱离了文档流,不影响周围的元素。但是,对元素进行清理实际上为前面的浮动元素流出了垂直空间。
清理是一个有用的布局工具,它让周围的元素为浮动元素留出空间。

css
.clear {
    clear: both;
}

比如这个场景:在一个 div 中有且只有两个浮动框(一左一右),此时如果在 div 上设置了背景颜色,由于浮动会脱离文档流,不占用空间,导致 div 高度为 0,从而不会显示背景色。

  • 一个解决方案就是在 div 中增加一个空元素,并清理它。但这需要添加不必要的代码。

  • 也可以不使用清理,而是将这个 div 也设置为浮动。但这也会导致一个问题,那就是 div 外层的元素又会受到影响。为此,有些人选择浮动页面上的所有元素,然后选择一个合适的元素(通常是页脚)做清理。

  • overflow 会自动的清理包含的任何浮动元素,但会影响它的表现(在某些情况下会产生滚动条或者阶段内容)。

  • 使用 :after 伪类和内容声明在指定的现有内容的末尾添加新的内容并做清理。

    css
    .clear:after {
        content: ".";
        height: 0;
        visibility: hidden;
        display: block;
        clear: both;
    }
  • 另外也可以使用 JavaScript 动态的添加元素再做清理。

附 1. 引用

  1. 《精通 CSS - 高级 Web 标准解决方案(第 2 版)》 - Andy Budd, Simon Collison, Cameron Moll 著;陈剑瓯 译。