翻译正在进行中。

我们已经在CSS模块介绍中了解过CSS盒模型 的基础知识。 本文将在这个问题上重述部分概念并且对一些知识细节进一步深入讲述。

前置知识: HTML 基础(学习 HTML介绍),,明白CSS是如何工作的 (学习 CSS介绍.)
目的: 重述CSS盒模型的基础并掌握更多相关细节知识。

盒 的属性

我们都知道, 文档中每一个元素在页面布局结构中均呈现为一个矩形的盒子, 我们简化为下面这个模型:

  • widthheight 设置了内容盒子的宽/高
  • padding 属性设置了盒子的内边距的宽度(具体属性比如 padding-bottom ,这样你就可以一次只设置一个边的内边距).
  • border 属性设置了盒子边框的宽度、样式和颜色(设置边框具体属性的参数还有很多)。
  • margin 属性设置了盒子与周围区域距离的大小,这个属性可以让其他的盒子与当前盒子产生距离(当然,这里一样有很多具体属性可用比如 margin-bottom )。

其它一些值得记住的点:

  • 如果盒子的高度被设置为百分比长度,那么盒子高度不会遵循这个设置了的百分比长度,而是总会采用盒子内容的高度,除非给它设置了一个绝对高度(例如,像素或者 em)。这比把页面上每个盒子的高度默认设置为视口高度的 100% 更方便。
  • 边框(border)也会忽略百分比宽度设置。
  • 外边距(margin)有一个特殊的行为,称为 外边距塌陷: 当两个盒子挨在一起时,二者之间的距离为两个挨着的外边距中最大的那个值,而不是二者的和。

注意: 有关更完整的概述和示例,请参阅 盒模型文章的部分 Box属性 部分

Overflow (溢出)

当用绝对的值设置盒子的大小时(比如,固定像素的 width 和 height),内容可能会超出设置的大小,此时内容就会溢出盒子。要控制这时候发生的事情,我们可以使用 overflow 属性。 该属性有几个可能的取值,不过最常用的是:

  • auto:如果内容太多,那么溢出的内容会被隐藏,滚动条显示出来,从而可以让用户滚动看到所有内容。
  • hidden: 如果内容太多,那么溢出的内容被隐藏了。
  • visible: 如果内容太多,溢出的内容显示在盒子之外(这通常是默认的行为)。

Note: 有关更完整的概述和示例,请参阅 盒模型文章的 “溢出” 部分

Background clip (背景剪裁)

盒背景由颜色和图像组成,堆叠在彼此之间(background-colorbackground-image)。它们被应用于一个盒并在该盒子下画。默认情况下,背景延伸到边框的外边缘。这通常很好,但在某些情况下可能会令人烦恼(如果您有一个平铺的背景图片,您只想扩展到内容的边缘呢?)这种行为可以通过设置background -clip属性。

注意: 示例请参阅 盒模型文章 背景裁剪部分

Outline

盒子的 outline 看起来像边框,但是它不是盒模型的一部分。它表现得像边框,但是是画在盒子之上,不会修改盒子的大小(具体来说,ouline 是画在边框盒之外,外边距区之内)。

注意: 当使用 outline 属性时要当心。在某些情况下,为了可访问性的原因,它会用作凸显网站可点击(active)部分,例如用户点击时的连接。如果您要使用 ouline 属性,请确保不要让它看起来像是点击时的连接,因为这会让用户混淆。

盒的高级属性

现在我们已经做了一个简单回顾,下面我们来看看一些有用的更高级的盒子属性。

设置宽和高的约束

其它一些属性可以用更灵活的方式控制内容盒的大小  —  是通过设置大小约束,而不是设置一个绝对大小。这是通过属性 min-widthmax-widthmin-heightmax-height 实现的。

一个明显的用处是,如果想通过设置将一个布局的外层容器的宽度设置为百分比,从而让布局的宽度变得灵活,不过又不想让它变得太宽或者太窄,因为这样布局就开始看起来很糟糕。一个选择是用响应式网页设计技术(之后我们会讲到),但是更简单的方法也许只是给布局一个最大和最小宽度约束即可:

width: 70%;
max-width: 1280px;
min-width: 480px;

您可以将这段代码与以下代码结合,可以将应用这段代码的容器在它的父容器内居中:

margin: 0 auto;

0会使顶部和底部边距为0,而auto(在这种情况下)共享父容器左右边距之间的可用空间使它居中。 最终的呈现的效果是:当父容器在最小和最大宽度限制内时,它将填满整个视口宽度;当父容器超过1280px宽度时,布局将保持在1280px宽,并开始在可用空间内居中。 当宽度低于480px时,视口将小于容器,您必须滚动才能看得到完全的内容。

以上的代码示例请见 min-max-container.html (see the source code).

max-width属性的另一个好处是可以将容器内的媒体(例如图像和视频)控制在容器内。 回到上面的例子,图像会引起一个问题——起初它的显示正常,但当容器变得比图像更窄时,图像开始溢出容器(因为它是一个固定的宽度)。 要应对这类图像的问题,我们可以在其上设置以下声明:

display: block;
margin: 0 auto;
max-width: 100%;

前两条样式规则可以使它的展示行为像一个块元素并且在父容器内居中。真正神奇的是第三条——这个限制了图像的宽度使它的最大宽度与父容器的宽度相等。因此,当父容器宽度缩小到小于图像的宽度时,图像会一起缩小。

您可以在 min-max-image-container.html (see the source code) 尝试以上修改过的代码。

注意: 以上技术有很好的跨平台性,可以在 Internet Explorer 7 上运行。

完全改变盒模型

一个框的总宽度是它的widthpadding-rightpadding-leftborder-rightborder-left属性之和。 在某些情况下比较麻烦(例如,如果您想要一个宽度为50%的框(box),同时边框(border)和填充(padding)以像素为单位表示?)为了避免这种问题,可以使用属性box-sizing。 使用 border-box属性,它将框模型更改为新的框模型:

我们来看一个生动的例子。 我们将设置两个相同的<div>元素,赋予每个元素相同的width,border和padding。 我们还将使用一些 JavaScript 脚本来打印每个框的宽度的计算值(最终屏幕上的像素值)。 唯一的区别是上面的使用默认值,而下面我们设置了box-sizing: border-box

首先,HTML为:

<div class="one"></div>
<div class="two"></div>

然后CSS为:

html {
  font-family: sans-serif;
  background: #ccc;
}

.one, .two {
  background: red;
  width: 300px;
  height: 150px;
  padding: 20px;
  border: 10px solid black;
  margin: 20px auto;
}

.two {
  box-sizing: border-box;
}

最后,我们用 JavaScript 脚本计算了两个框的计算宽度值:

var one = document.querySelector('.one');
var two = document.querySelector('.two');

function outputWH(box) {
  var width = box.offsetWidth;
  var height = box.offsetHeight;
  box.textContent = 'Width: ' + width + 'px, Height: ' + height + 'px.'
}

outputWH(one);
outputWH(two);

由上面的例子得出以下结果:

那么这里发生了什么? 正如你所料,第一个框的宽度和高度等于content + padding + border。 然而,第二个框的宽度和高度等于通过CSS设置在 content 的宽度和高度。 padding 和 border 并没有添加到总宽度和高度上; 相反,他们已经占用了一些内容的空间,使 content 更小,并保持总体尺寸相同。

您还可以看到此示例在 box-sizing-example.html (see the source code)上运行.

盒子的显示类型

迄今为止我们所说的都是针对块级元素的盒子。不过,CSS 还有元素行为不同的其它类型的盒子。元素的盒子类型是由 display 属性指定的。

常见的display的类型

 display 可以有很多种不同的值, 其中三种常见的值为 block, inline, 和 inline-block.

  • 块盒(block box)是被定位为堆放在其它盒子之上的盒子(即盒子之前以及之后的内容出现在不同的行上),并且可以给它设置高度和宽度。上面所述的整个盒模型都适用于块盒。
  • 行内盒(inline box)与块盒相反:它跟随文档的文本流堆放(即,它会与周围的文本和其它行内元素出现在同一行,并且其内容会像段落中的文本行一样,随着文本流换行)。宽度和高度设置对行内盒无效;在行内盒上的所有内边距、外边距和边框设置会改变周围文本的位置,但是不会影响周围块盒的位置。
  • 行内块盒(inline-block box)介于前两者之间: 它会像行内盒一样,跟随周围的文本流堆放,不会在其前后创建换行;不过,它可以像块盒一样,使用宽度和高度设置大小,并且维护其块完整性 — 它不会跨段落行换行(对于一行文本容纳不下的行内盒,会落到第二行上,因为第一行上没有足够的空间容纳它,并且不会跨两行换行)。

块级元素默认设置为 display: block; ,行内元素默认设置为 display: inline; 。

Note: See The box model article's Types of CSS boxes section for a more complete overview and an example.

不常见的display类型

同时, display 属性也有一些不常用的值,在以后你将会遇到。其中一些已经出现了有一段时间,并且可以很好的被支持, 而另一些则比较新,不能够被很好的支持. 这些值通常是为了使创建网页/网页应用更简单而被创造出来。最被关注的有这些:

  • display: table — 允许你像处理table布局那样处理非table元素,而不是滥用HTML的<table>标签来达到同样的目的。了解更多相关信息,请查看 CSS tables.
  • display: flex — 允许你处理一些困扰CSS已久的一些传统布局问题, such as laying out a series of containers in flexible equal width columns, or vertically centering content. 了解更多相关信息,请查看 Flexbox.
  • display: grid — gives CSS a native way of easily implementing grid systems, whereas it has traditionally relied on somewhat hack-ish CSS grid frameworks. Our CSS Grids article explains how to use traditional CSS grid frameworks, and gives a sneak peek at native CSS Grids.

What's next

在一小段快速的概览之后,我们看了一些更加高级的用来操纵框(box)的CSS特性,接着又接触了一些高级的布局特性,结束了这篇文章。在这之后,我们现在将继续下去,来看看背景(background)。

文档标签和贡献者

 最后编辑者: sputnikW,