CSS盒模型(Box Model)是CSS布局的核心概念之一,它描述了如何对文档中的元素进行布局和尺寸计算。每个元素都会生成一个矩形的盒子,这个盒子由几个部分组成,包括内容(content)、内边距(padding)、边框(border)和外边距(margin)。了解这些部分如何相互作用对于创建有效的网页布局至关重要。

盒模型的组成部分
-
内容(Content):这是元素的实际内容区域,如文本、图片等。内容的尺寸可以通过
width和height属性直接设置。 -
内边距(Padding):内边距是内容区域与边框之间的空间。内边距是透明的,可以通过
padding-top、padding-right、padding-bottom、padding-left或简写属性padding来设置。 -
边框(Border):边框环绕在内边距和内容之外。边框的粗细、样式和颜色可以通过
border-width、border-style和border-color(或简写属性border)来设置。 -
外边距(Margin):外边距是边框之外的空间,用于控制元素与其他元素之间的距离。外边距是透明的,可以通过
margin-top、margin-right、margin-bottom、margin-left或简写属性margin来设置。
盒模型的类型

CSS盒模型主要有两种类型:标准盒模型(Standard Box Model)和IE盒模型(也称为怪异模式或IE盒模型,Quirks Mode Box Model)。
-
标准盒模型:元素的宽度和高度仅包括内容区域,不包括内边距、边框和外边距。如果设置了内边距(padding)或边框(border),元素的宽度和高度会相应增加。
-
IE盒模型:在IE盒模型中,元素的宽度和高度包括内容、内边距和边框,但不包括外边距。这意呀着,如果你设置了一个元素的宽度和高度,并添加了内边距和边框,元素的总体宽度和高度不会改变,而是向内压缩内容区域来适应。
如何改变盒模型
CSS3引入了box-sizing属性,允许我们改变盒模型的计算方式。
content-box:默认值,使用标准盒模型。border-box:使用IE盒模型的计算方式,即元素的宽度和高度包括内容、内边距和边框。
通过设置box-sizing: border-box;,我们可以更直观地控制元素的尺寸,避免因为内边距和边框而导致的布局问题。
1 边框(border)

border可以设置元素的边框。边框有三部分组成:边框宽度(粗细) 边框样式 边框颜色
border : border-width || border-style || border-color

CSS 边框属性允许你指定一个元素边框的样式和颜色。
边框样式 border-style 可以设置如下值:
- none:没有边框即忽略所有边框的宽度(默认值)
- solid:边框为单实线(最为常用的)
- dashed:边框为虚线
- dotted:边框为点线
CSS 边框属性允许你指定一个元素边框的样式和颜色。
border: 1px solid red; 没有顺序
请给一个 200*200 的盒子,设置上边框为红色,其余边框为蓝色(提示:一定注意边框的层叠性:

.box {
width: 200px;
height: 200px;
/* 分别设置边框的样式、宽度和颜色 */
border-top: 2px solid red; /* 上边框为红色 */
border-right: 2px solid blue; /* 右边框为蓝色 */
border-bottom: 2px solid blue; /* 下边框为蓝色 */
border-left: 2px solid blue; /* 左边框为蓝色 */
/* 或者使用简写属性,但为了清晰展示如何分别设置,上面已经分开写了 */
border-style: solid;
border-width: 2px;
border-color: blue;
border-top-color: red;
}
将 border-collapse 属性的值设置为 collapse 时,表格的相邻边框会合并为一个单一的边框
border-collapse 属性确实用于控制浏览器绘制表格边框的方式,特别是它如何处理相邻单元格(<td> 和 <th>)之间的边框。当你将 border-collapse 属性的值设置为 collapse 时,表格的相邻边框会合并为一个单一的边框,而不是每个单元格都绘制自己的边框,这可能会导致边框看起来更宽或更粗(实际上是多个边框重叠在一起的效果)。
使用 border-collapse: collapse; 可以让表格的边框看起来更加整洁和统一,因为它消除了相邻边框之间的空隙。这在视觉上更为吸引人,特别是在创建具有复杂边框样式的表格时。
默认情况下,border-collapse 的值是 separate,这意味着表格的边框是分开的,每个单元格都会绘制自己的边框,这可能会导致在相邻单元格的边框之间出现双重的边框线(如果每个单元格都设置了边框的话)。
下面是一个简单的例子,展示了 border-collapse 属性的使用:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
table, th, td {
border: 1px solid black;
}
table {
border-collapse: collapse; /* 让表格的边框合并为一个单一的边框 */
}
</style>
</head>
<body>
<h2>带有 border-collapse: collapse 的表格</h2>
<table>
<tr>
<th>首列</th>
<th>次列</th>
</tr>
<tr>
<td>行 1, 列 1</td>
<td>行 1, 列 2</td>
</tr>
<tr>
<td>行 2, 列 1</td>
<td>行 2, 列 2</td>
</tr>
</table>
</body>
</html>
在这个例子中,即使每个 <th> 和 <td> 元素都设置了 border: 1px solid black;,但因为 table 元素使用了 border-collapse: collapse;,所以相邻的边框会合并成一个单一的边框,而不是每个单元格都显示自己的边框。
边框(border)确实会影响盒子(box)的实际大小
边框(border)确实会影响盒子(box)的实际大小。在CSS中,一个元素的盒子模型由内容(content)、内边距(padding)、边框(border)和外边距(margin)组成。这些组成部分共同决定了元素在页面上占据的空间大小。
- 内容(Content):这是元素的实际内容区域,其大小可以通过
width和height属性来设置。 - 内边距(Padding):内边距是内容区域与边框之间的空间。它不会直接增加元素的可视宽度或高度,但会增加元素的总大小(包括边框和外边距)。
- 边框(Border):边框环绕在内边距和内容的外围。边框的宽度会直接增加到元素的总宽度和总高度上。
- 外边距(Margin):外边距是边框之外的空间,用于控制元素与其他元素之间的距离。它不会直接影响元素本身的宽度和高度,但会影响元素与其他元素之间的空间。
因此,当你为一个元素设置边框时,这个边框的宽度会被添加到元素的总宽度和总高度上。这意呀着,如果你有一个宽度为100px的元素,并且为其设置了2px的边框,那么该元素在页面上占据的实际宽度将是104px(100px的内容宽度 + 2px的左边框 + 2px的右边框)。
要注意的是,CSS中的box-sizing属性可以控制盒子模型的计算方式。默认情况下,box-sizing的值为content-box,这意味着元素的宽度和高度仅包括内容区域,而不包括内边距、边框和外边距。但是,如果你将box-sizing设置为border-box,那么元素的宽度和高度将包括内容、内边距和边框,但不包括外边距。这样,无论边框的宽度如何变化,元素的总宽度和总高度都将保持不变。
padding(内边距)用来“撑开”盒子
padding(内边距)在CSS布局中是一个非常有用的属性,它可以被巧妙地用来调整元素内部的空间,并且有时候还可以用来“撑开”盒子:
在导航栏的设计中,如果每个导航项(比如<li>元素或<a>链接)的内容长度不同,直接为每个导航项设置固定的宽度可能会导致布局上的不美观或不必要的空间浪费。相反,通过合理地使用padding,你可以确保每个导航项都有足够的内部空间来容纳其内容,同时保持整体布局的一致性。
- 自动宽度:当你不为导航项设置
width属性时,它们通常会根据其内容自动调整宽度。这时,padding会在内容周围添加额外的空间,但不会改变内容本身的宽度,只会影响整个导航项的可视宽度。

当然,以下是一个具体的例子,用于说明当盒子(例如一个div元素)没有指定width或height属性时,padding是如何影响盒子的可视尺寸的。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Padding Example</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="padded-box">这是一个有内边距的盒子</div>
</body>
</html>
在这个例子中,我们将为.padded-box类设置padding,但不设置width或height。同时,为了更清楚地看到padding的效果,我们还可以添加一些border。
.padded-box {
/* 不设置 width 或 height */
padding: 20px; /* 设置内边距为 20px */
border: 2px solid black; /* 添加边框以便更清楚地看到盒子的尺寸 */
/* box-sizing 默认为 content-box,但为了清晰起见,我们可以显式设置它 */
box-sizing: content-box; /* 实际上,这个设置是默认的,但在这里是为了说明 */
/* 我们可以添加一些背景色以便更好地看到盒子的范围 */
background-color: lightblue;
}
当你将上述HTML和CSS代码放入一个HTML文件中并在浏览器中打开时,你会看到一个带有边框和内边距的蓝色盒子。这个盒子的宽度会扩展到其父元素(在这个例子中是<body>元素)的可用宽度(减去任何可能的边距或边框),但高度会仅由内容和内边距和边框决定。
由于我们没有为.padded-box设置width或height,所以盒子的宽度和高度是自适应的。 然而,padding确实增加了盒子内容区域周围的空间,这从视觉上使盒子看起来更大了。如果我们将box-sizing更改为border-box,那么盒子的宽度将包括内容、内边距和边框的总宽度,但在这个例子中,由于我们没有设置width,所以实际行为仍然是自适应的。不过,如果我们设置了width,并且box-sizing为border-box,那么增加padding或border时,盒子的总宽度将保持不变,而内容区域会相应减小。
2 外边距(margin)
块级元素水平居中
在CSS中,要实现块级盒子(如div)的水平居中,通常需要将左右的外边距(margin-left 和 margin-right)设置为auto,并且这个盒子必须有一个指定的宽度(width)。这是因为,当块级元素的左右外边距被设置为auto时,浏览器会自动计算这些外边距的大小,以便在可用空间内均匀分布内容,从而达到水平居中的效果。
然而,这种方法有几个关键点需要注意:
-
指定宽度:块级元素默认会扩展到其父元素的全部可用宽度(除非受到其他CSS属性的影响,如
float、position的absolute或fixed值,或是显式设置了width)。因此,如果不为元素指定一个宽度,那么设置margin-left和margin-right为auto将不会有任何效果,因为元素已经占据了全部可用空间。 -
自动外边距:将
margin-left和margin-right设置为auto是告诉浏览器自动调整这些外边距的大小,以便在父元素的宽度内居中元素。如果元素只有一个方向的外边距被设置为auto(例如只有margin-left),那么它通常会被推到一边,而不是居中。
以下是一个简单的例子,展示了如何使用自动外边距来实现块级盒子的水平居中:

<!DOCTYPE html>
<html>
<head>
<style>
.center-box {
width: 50%; /* 指定宽度 */
margin-left: auto; /* 左边距自动 */
margin-right: auto; /* 右边距自动 */
background-color: lightblue; /* 背景色以便更好地看到效果 */
}
</style>
</head>
<body>
<div class="center-box">这个盒子是水平居中的。</div>
</body>
</html>
以下是一个简单的例子,展示了如何使用自动外边距来实现块级盒子的推到一边:

行内元素或者行内块元素水平居中给其父元素添加 text-align:center
对于行内元素(如<span>、<a>等)或行内块元素(如设置了display: inline-block;的<div>、<span>等),要实现它们的水平居中,通常不需要直接对这些元素本身进行操作,而是需要给它们的父元素设置text-align: center;样式。
text-align: center;属性会将其父元素内的行内内容(包括文本和行内元素,以及行内块元素)在水平方向上居中对齐。这意味着,只要这些元素是行内或行内块级的,并且它们的父元素具有text-align: center;样式,它们就会相对于父元素的宽度居中对齐。
这里有一个简单的例子来演示这一点:
<!DOCTYPE html>
<html>
<head>
<style>
.parent {
text-align: center; /* 使子元素水平居中 */
background-color: lightgrey; /* 背景色以便更好地看到效果 */
padding: 20px; /* 添加一些内边距以便更清楚地看到居中效果 */
}
.child {
display: inline-block; /* 设置为行内块元素 */
background-color: lightblue; /* 背景色以便更好地看到子元素 */
padding: 10px; /* 添加一些内边距以便更清楚地看到子元素 */
}
</style>
</head>
<body>
<div class="parent">
<span class="child">这是一个行内块元素,它将水平居中。</span>
<!-- 注意:这里的<span>实际上是行内元素,但因为我们设置了display: inline-block,所以它表现得像行内块元素 -->
</div>
</body>
</html>
在这个例子中,<span>元素通过display: inline-block;被转换成了行内块元素,并且由于它的父元素<div>具有text-align: center;样式,所以<span>元素在水平方向上被居中了。同样的效果也适用于其他行内或行内块元素。
外边距合并

相邻块元素垂直外边距的合并是CSS中一个常见的现象,它发生在两个或多个垂直相邻的块级元素之间。当这些元素之间的外边距相遇时,它们不会简单地叠加,而是会合并成一个单一的外边距,这个外边距的大小通常是这两个元素中外边距的较大值。
<html>
<head>
<style>
.box {
background-color: lightblue;
height: 100px; /* 为了让效果更明显,给盒子一个固定高度 */
}
.first-box {
margin-bottom: 20px; /* 每个.box元素都有20px的下外边距 */
}
.second-box {
margin-top: 20px; /* 每个.box元素都有20px的下外边距 */
}
</style>
</head>
<body>
<div class="first-box box">first-box</div>
<div class="second-box box">second-box</div>
</body>
</html>

对于两个嵌套关系(父子关系)的块元素,父元素有上外边距同时子元素也有上外边距,此时父元素会塌陷较大的外边距值。


这里有一个具体的例子来说明这一点:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>外边距合并-嵌套块级元素垂直外边距塌陷</title>
<style>
.father {
width: 200px;
height: 200px;
background-color: purple;
margin-top: 50px;
/* border: 1px solid red; */
/* border: 1px solid transparent; */
/* padding: 1px; */
overflow: hidden;
}
.son {
width: 100px;
height: 100px;
background-color: pink;
margin-top: 100px;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
</body>
</html>
解决思路:可以为父元素定义上边框: border: 1px solid red;
清除内外边距
网页元素很多都带有默认的内外边距,而且不同浏览器默认的也不一致。因此我们在布局前,首先要清除下网页元素的内外边距。
* {
padding:0; /* 清除内边距 */
margin:0; /* 清除外边距 */
}
注意:行内元素为了照顾兼容性,尽量只设置左右内外边距,不要设置上下内外边距。但是转换为块级和行内块元素就可以了



















