目录
- [1. 区块盒子与行内盒子](#1. 区块盒子与行内盒子)
- [2. 外部显示类型](#2. 外部显示类型)
- [3. 内部显示类型](#3. 内部显示类型)
- [4. 不同显示类型的例子](#4. 不同显示类型的例子)
- [5. 什么是CSS盒模型](#5. 什么是CSS盒模型)
-
- [5.1 盒模型的各个部分](#5.1 盒模型的各个部分)
- [5.2 CSS标准盒模型](#5.2 CSS标准盒模型)
- [5.3 CSS替代盒模型](#5.3 CSS替代盒模型)
- [6. 玩转盒模型](#6. 玩转盒模型)
-
- [6.1 使用浏览器开发者工具来查看盒模型](#6.1 使用浏览器开发者工具来查看盒模型)
- [7. 外边距、内边距和边框](#7. 外边距、内边距和边框)
-
- [7.1 外边距](#7.1 外边距)
- [7.2 外边距折叠](#7.2 外边距折叠)
- [7.3 边框](#7.3 边框)
- [7.4 内边距](#7.4 内边距)
- [8. 盒子模型和行内盒子](#8. 盒子模型和行内盒子)
- [9. 使用display: inline-block](#9. 使用display: inline-block)
- 参考
1. 区块盒子与行内盒子
在CSS中,我们有几种类型的盒子,一般分为区块盒子和行内盒子。类型值的是盒子在页面流中的行为方式以及页面上其他盒子的关系。盒子有内部显示和外部显示两种类型。
一般来说,可以使用display属性为显示类型设置各种值,该属性可以有多种值。
2. 外部显示类型
一个拥有block外部显示类型的盒子会表现出以下行为:
盒子会换行。
width和height属性可以发挥作用。
内边距、外边距和边框会将其他元素从当前盒子周围推开。
如果未指定width,方框将沿行向扩展,以填充其容器中的可用空间。在大多数情况下,盒子会变得与其容器一样宽,占据可用空间的100%。
某些HTML元素,如<h1>和<p>,默认使用block作为外部显示类型。
一个拥有inline外部显示类型的盒子会表现以下行为:
盒子不会产生换行。
width和height属性将不起作用。
垂直方向的内边距、外边距以及边框会被应用但是不会把其他处于inline状态的盒子推开。
水平方向的内边距、外边距以及边框会被应用且会把其他处于inline状态的盒子推开。
某些HTML元素,如<a>、<span>、<em>以及<strong>,默认使用inline作为外部显示类型。
3. 内部显示类型
盒子还有内部显示类型,它决定了盒子内元素的布局方式。
区块和行内布局是网络上的默认行为方式。默认情况下,在没有任何其他指令的情况下,方框内的元素也会以标准流的方式布局,并表现为区块或行内盒子。
例如,可以通过设置display: flex;来更改内部显示类型。该元素仍将使用外部显示类型block但内部显示类型将变为flex。该方框的任何直接子代都将成为弹性项,并按照弹性盒子规范执行。
当你继续详细学习CSS布局时,将会遇到flex以及盒子可以具有的其他各种内部值,例如grid。
4. 不同显示类型的例子
下面的示例中有三个不同的HTML元素,它们的外部显示类型都是block。
在CSS中添加了边框的段落。浏览器会将其渲染为一个盒子框。段落从新行开始,并扩展整个可用宽度。
使用display: flex布局的列表。这就为容器的子项建立了弹性布局。列表本身是一个区块盒子,与段落一样,会扩展到整个容器的宽度,然后换行。
一个块级段落,内含两个<span>元素。这些元素通常是inline,但是其中一个元素的类是block,令其被设置为display: block。
html
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>learning CSS</title>
<link href="learning.css" rel="stylesheet" type="text/css">
</head>
<body>
<p>I am a paragraph. A short one.</p>
<ul>
<li>Item One</li>
<li>Item Two</li>
<li>Item Three</li>
</ul>
<p>
I am another paragraph. Some of the <span class="block">words</span> have been
wrapped in a <span>span element</span>.
</p>
</body>
</html>
css
body {
font-family: sans-serif;
}
p,
ul {
border: 2px solid rebeccapurple;
padding: 0.2em;
}
.block,
li {
border: 2px solid blue;
padding: 0.2em;
}
ul {
display: flex;
list-style: none;
}
.block {
display: block;
}

下面示例中,会看到inline元素是如何表现的。
第一段中的<span>元素默认为行级,因此不会强制换行。
设置为display: inline-flex的<ul>元素会创建一个行向行向盒子,其中包含一些弹性项目。
这两个段落都设置为display: inline。行向弹性容器和段落都在一行中流动,而不是分成两行。
html
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>learning CSS</title>
<link href="learning.css" rel="stylesheet" type="text/css">
</head>
<body>
<p>
I am a paragraph. Some of the
<span>words</span> have been wrapped in a <span>span element</span>.
</p>
<ul>
<li>Item One</li>
<li>Item Two</li>
<li>Item Three</li>
</ul>
<p class="inline">I am a paragraph. A short one.</p>
<p class="inline">I am another paragraph. Also a short one.</p>
</body>
</html>
css
body {
font-family: sans-serif;
}
p,
ul {
border: 2px solid rebeccapurple;
}
span,
li {
border: 2px solid blue;
}
ul {
display: inline-flex;
list-style: none;
padding: 0;
}
.inline {
display: inline;
}


5. 什么是CSS盒模型
CSS盒模型整体上使用于区块盒子,它定义了盒子的不同部分如何协同工作,以创建一个在页面上可以看到的盒子。行内盒子使用的只是盒模型中定义的部分行为。
为了增加复杂性,有一种标准盒模型和一种替代盒模型。默认情况下,浏览器使用标准盒模型。
5.1 盒模型的各个部分
CSS中组合一个区块盒子需要:
内容盒子:显示内容的区域;使用inline-size和block-size或width和height等属性确定其大小。
内边距盒子:填充位于内容周围的空白处;使用padding和相关属性确定其大小。
边框盒子:边框盒子包住内容和任何填充;使用border和相关属性确定其大小。
外边距盒子:外边距是最外层,其包裹内容、内边距和边框,作为该盒子与其他元素之间的空白;使用margin和相关属性确定其大小。

5.2 CSS标准盒模型
在标准盒模型中,如果在盒子上设置了inline-size和block-size或width和height属性值,这些值就定义了内容盒子的inline-size和block-size。然后将任何内边距和边框添加到这些尺寸中,以获得盒子所占的总大小。
假设一个盒子的CSS如下:
css
.box {
width: 350px;
height: 150px;
margin: 10px;
padding: 25px;
border: 5px solid black;
}
方框实际占用的空间宽为350 + 25 + 25 + 5 + 5 = 410px,高为150 + 25 + 25 + 5 + 5 = 210px。
5.3 CSS替代盒模型
在替代盒模型中,任何宽度都是页面上可见方框的宽度。内容区域的宽度是该宽度减去填充和边框的宽度。无需将边框和内边距相加,即可获得盒子的实际大小。
要为某个元素使用替代模型,可对其设置box-sizing: border-box。
css
.box {
box-sizing: border-box;
}
假设一个盒子的CSS与上例相同:
css
.box {
width: 350px;
inline-size: 350px;
height: 150px;
block-size: 150px;
margin: 10px;
padding: 25px;
border: 5px solid black;
}
盒子实际占用的空间在行向(水平)为350px,在块内(垂直)为150px。内容盒子实际占用的空间宽为350 - 25 - 25 - 5 - 5 = 290px,高为150 - 25 - 25 - 5 - 5 = 90px。
要在所有元素中使用替代盒模型(这是开发人员的常见选择),请在<html>元素上设置box-sizing属性,并将所有其他元素设置为继承该值:
css
html {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
6. 玩转盒模型
在下面的示例中,可以看到两个盒子。两个盒子的类都是.box,因此具有相同的width、height、margi、border和padding。唯一不同的是,第二个盒被设置为使用替代盒模型。
html
<!doctype html>
<html lang="en-US">
<head>
<meta charset="utf-8" />
<title>learning CSS</title>
<link rel="stylesheet" href="learning.css" />
</head>
<body>
<div class="box">I use the standard box model.</div>
<div class="box alternate">I use the alternate box model.</div>
</body>
</html>
css
.box {
border: 5px solid rebeccapurple;
background-color: lightgray;
padding: 40px;
margin: 40px;
width: 300px;
height: 150px;
}
.alternate {
box-sizing: border-box;
width: 380px;
height: 230px;
}

6.1 使用浏览器开发者工具来查看盒模型
浏览器开发者工具可以使你更容易地理解盒模型。

7. 外边距、内边距和边框
7.1 外边距
外边距是盒子周围一圈看不到的空间。它会把其他元素推离盒子。外边距属性值可以为正也可以为负。在盒子一侧设置负值会导致盒子和页面上的其他内容重叠。无论使用标准模型还是替代模型,外边距总是在计算可见部分后额外添加。
我们可以使用margin属性一次性控制一个元素的所有外边距,或者每边单独使用等价的普通属性控制:
margin-top
margin-right
margin-bottom
margin-left
html
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>learning CSS</title>
<link href="learning.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="container">
<div class="box">Change my margin.</div>
</div>
</body>
</html>
css
.container {
border: 5px solid blue;
margin: 40px;
}
.box {
border: 5px solid rebeccapurple;
background-color: lightgray;
padding: 10px;
height: 100px;
/* try changing the margin properties: */
margin: 20px -10px 40px -20px;
}

7.2 外边距折叠
根据外边距相接触的两个元素是正边距还是负边距,结果会有所不同。
两个正外边距将合并为一个外边距。其大小等于最大的单个外边距。
两个负外边距会折叠,并且使用最小的值。
如果其中一个外边距为负值,其值将从总值中减去。
html
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>learning CSS</title>
<link href="learning.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="container">
<p class="one">I am paragraph one.</p>
<p class="two">I am paragraph two.</p>
</div>
</body>
</html>
css
.container {
border: 5px solid blue;
margin: 40px;
}
p {
border: 5px solid rebeccapurple;
background-color: lightgray;
padding: 10px;
}
.one {
margin-bottom: 50px;
}
.two {
margin-top: 30px;
}



外边距何时折叠,何时不折叠,由许多规则决定。需要记住的主要一点是,外边距折叠是指在使用外边距创建空间时,如果没有获得预期的空间,就会发生外边距折叠。
7.3 边框
边框是在边距和填充盒子之间绘制的。如果你正在使用标准的盒模型,边框的大小将添加到框的宽度和高度。如果你使用的是替代盒模型,边框越大会使内容框越小,因为它会占用一些可用的宽度和高度。
为边框设置样式时,有大量的属性可以使用------有四个边框,每个边框都有样式、宽度和颜色,我们可能需要对它们进行操作。
可以使用border属性一次性设置所有四个边框的宽度、颜色和样式。
欲分别设置每边的属性,可以使用:
border-top
border-right
border-bottom
border-left
欲设置所有边的宽度、样式或颜色,可以使用:
border-width
border-style
border-color
欲设置单条边的宽度、样式或颜色,可以使用最细粒度的普通属性之一:
border-top-width
border-top-style
border-top-color
border-right-width
border-right-style
border-right-color
border-bottom-width
border-bottom-style
border-bottom-color
border-left-width
border-left-style
border-left-color
html
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>learning CSS</title>
<link href="learning.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="container">
<div class="box">Change my borders.</div>
</div>
</body>
</html>
css
body {
font-family: sans-serif;
}
.container {
margin: 40px;
padding: 20px;
border-top: 5px dotted green;
border-right: 1px solid black;
border-bottom: 20px double rgb(23 45 145);
}
.box {
padding: 20px;
background-color: lightgray;
border: 1px solid #333333;
border-top-style: dotted;
border-right-width: 20px;
border-bottom-color: hotpink;
}

7.4 内边距
内边距位于边框和内容区域之间,用于将内容推离边框。与外边距不同,内边距不能为负数。任何应用与元素的背景都会显示在内边距后面。
我们可以使用padding简写属性一次性控制元素所有边,或者每边单独使用等价的普通属性:
padding-top
padding-right
padding-bottom
padding-left
html
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>learning CSS</title>
<link href="learning.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="container">
<div class="box">Change my padding.</div>
</div>
</body>
</html>
css
body {
font-family: sans-serif;
}
.box {
border: 5px solid rebeccapurple;
background-color: lightgray;
padding: 0 30px 40px 4em;
}
.container {
border: 5px solid blue;
margin: 40px;
padding: 20px;
}

8. 盒子模型和行内盒子
以上所有的方法都完全适用于块级盒子。某些属性也使用于行内盒子,例如由<span>元素创建的盒子。
下面的示例中<span>的宽度和高度都被忽略了。左右内边距、左右外边距和左右边框会将其他内容从方框中推开。
html
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>learning CSS</title>
<link href="learning.css" rel="stylesheet" type="text/css">
</head>
<body>
<p>
I am a paragraph and this is a <span>span</span> inside that paragraph. A span
is an inline element and so does not respect width and height.
</p>
</body>
</html>
css
body {
font-family: sans-serif;
}
p {
border: 2px solid rebeccapurple;
width: 200px;
}
span {
margin: 20px 10px 20px 10px;
padding: 20px 10px 20px 10px;
width: 80px;
height: 150px;
background-color: lightblue;
border: 2px solid blue;
}

9. 使用display: inline-block
display: inline-block是display的一个特殊值,它提供了介于inline和block之间的中间位置。如果不希望项目换行,但又希望它使用width和height值并避免出现上述重叠现象,请使用它。
一个元素使用display: inline-block,实现我们需要的块级的部分效果:
设置width和height属性会生效。
padding、margin和border会推开其他元素。
不过,它不会换行,只有在明确添加width和height属性后,才会变得比其内容大。
html
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>learning CSS</title>
<link href="learning.css" rel="stylesheet" type="text/css">
</head>
<body>
<p>
I am a paragraph and this is a <span>span</span> inside that paragraph. A span
is an inline element and so does not respect width and height.
</p>
</body>
</html>
css
body {
font-family: sans-serif;
}
p {
border: 2px solid rebeccapurple;
width: 300px;
}
span {
margin: 20px;
padding: 20px;
width: 80px;
height: 50px;
background-color: lightblue;
border: 10px solid blue;
display: inline-block;
}

当你想要通过添加padding来扩大链接的点击范围时,这个功能就派上用场了。<a>和<span>一样是一个行内元素,可以使用display: inline-block在其上设置内边距,使用户更容易点击链接。
html
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>learning CSS</title>
<link href="learning.css" rel="stylesheet" type="text/css">
</head>
<body>
<nav>
<ul class="links-list">
<li><a href="">Link one</a></li>
<li><a href="">Link two</a></li>
<li><a href="">Link three</a></li>
</ul>
</nav>
</body>
</html>
css
ul {
font-family: sans-serif;
display: flex;
list-style: none;
border: 1px solid #000;
}
li {
margin: 5px;
}
.links-list a {
background-color: rgb(179 57 81);
color: #fff;
display: inline-block;
text-decoration: none;
padding: 1em 2em;
}
.links-list a:hover {
background-color: rgb(66 28 40);
color: #fff;
}

参考
1、盒模型