CSS盒子模型
# 五、CSS盒子模型
# 1. 元素的显示模式
# 块元素(block)
又称:块级元素 特点:
- 在页面中 独占一行 ,不会与任何元素共用一行,是从上到下排列的。
- 默认宽度:撑满 父元素 。
- 默认高度:由 内容 撑开。
- 可以 通过CSS设置宽高。
# 行内元素(inline)
又称:内联元素 特点:
- 在页面中 不独占一行 ,一行中不能容纳下的行内元素,会在下一行继续从左到右排列。
- 默认宽度:由 内容 撑开。
- 默认高度:由 内容 撑开。
- 无法 通过CSS设置宽高。
# 行内块元素(inline-block)
又称:内联块元素 特点:
- 在页面中 不独占一行 ,一行中不能容纳下的行内元素,会在下一行继续从左到右排列。
- 默认宽度:由 内容 撑开。
- 默认高度:由 内容 撑开。
- 可以 通过CSS设置宽高。
注意: 元素早期只分为: 行内元素 、 块级元素 ,区分条件也只有一条:"是否独占一行",如果按照这种分类方式,行内块元素应该算作行内元素。
# 2. 总结各元素的显示模式
显示模式 | 特点 |
---|---|
块元素 | 独占一行 宽度撑满父元素 高度由内容撑开 可以设置宽高 |
行内元素 | 不独占一行 宽度由内容撑开 高度由内容撑开 不可以设置宽高 |
行内块元素 | 不独占一行 宽度由内容撑开 高度由内容撑开 可以设置宽高 |
# 块元素(block)
1. 主体结构标签:<html>、<body> 2. 排版标签:<h1> ~ <h6>、<hr>、<p>、<pre>、<div> 3. 列表标签:<ul>、<ol>、<li>、<dl>、<dt>、<dd> 4. 表格相关标签:<table>、<tbody>、<thead>、<tfoot>、<tr>、<caption> 5. <form>与<option>
1
2
3
4
5
# 行内元素(inline)
1. 文本标签:<br>、<em>、<strong>、<sup>、<sub>、<del>、<ins> 2. <a>与<label>
1
2
# 行内块元素(inline-block)
1. 图片:<img> 2. 单元格:<td>、<th> 3. 表单控件:<input>、<textarea>、<select>、<button> 4. 框架标签:<iframe>
1
2
3
4
# 修改元素的显示模式
通过CSS 中的 display 属性可以修改元素的默认显示模式,常用值如下:
值 | 描述 |
---|---|
none | 元素会被 隐藏 。 |
block | 元素将作为 块级元素 显示。 |
inline | 元素将作为 内联元素 显示。 |
inline-block | 元素将作为 行内块元素 显示。 |
# 3. 盒子模型
# 3.1 什么是CSS 盒模型?
前端布局中,一个元素的外边距(margin)、 边框(border)、内边距(padding)、内容(content)组成一个盒模型。盒模型可分为标准盒模型 和 代替(IE)盒模型。
# 3.2 盒子模型的组成
CSS 会把所有的 HTML 元素都看成一个 盒子 ,所有的样式也都是基于这个盒子。
1. margin(外边距): 盒子与外界的距离。
2. border(边框): 盒子的边框。
3. padding(内边距): 紧贴内容的补白区域。
4. content(内容): 元素中的文本或后代元素都是它的内容。
2
3
4
图示如下:
盒子的大小 = content + 左右 padding + 左右 border 。
关于默认宽度=所谓的默认宽度,就是 不设置 width 属性时 ,元素所呈现出来的宽度。
总宽度 = 父的content — 自身的左右margin。
内容区的宽度 = 父的content — 自身的左右margin — 自身的左右border — 自身的左右 padding。
注意:外边距margin不会影响盒子的大小,但会影响盒子的位置。
# 3.3 标准盒模型
在标准模型中,如果你给盒设置 width
和 height
,实际设置的是内容区域( content box)的宽高。 padding
和 border
再加上设置的宽高一起决定整个盒子的大小。
示例:
.box {
width: 100px;
height: 50px;
margin: 10px;
padding: 25px;
border: 5px solid black;
}
2
3
4
5
6
7
如果使用标准模型,元素总宽度 = 160px (100+25+25+5+5),总高度 = 110px (50 + 25 + 25 + 5 + 5),即内容区域content box
加 padding
和 border
。
注: margin 不计入实际大小 —— 当然,它会影响盒子在前端所占空间,但是影响的是盒子外部空间。
# 3.4 代替(IE)盒模型
你可能会认为盒子的大小还要加上边框和内边距,这样很麻烦。 因为这个原因,css还有一个替代盒模型。使用这个模型,所有宽度都是可见宽度,所以内容宽度是该宽度减去边框和填充部分。使用上面相同的样式得到总宽高是 width = 100px, height = 50px。
默认浏览器会使用标准模型。如果需要使用替代模型,您可以通过为其设置 box-sizing: border-box
来实现。 这样就可以告诉浏览器使用 border-box
来定义区域,从而设定您想要的大小。
.box {
box-sizing: border-box;
}
2
3
# 3.5 box-sizing属性
CSS中的 box-sizing
属性用于告诉浏览器如何计算一个元素是总宽度和总高度
在 CSS盒子模型 (opens new window) 的默认定义里,你对一个元素所设置的 width
(opens new window) 与 height
(opens new window) 只会应用到这个元素的内容区。如果这个元素有任何的 border
(opens new window) 或 padding
(opens new window) ,绘制到屏幕上时的盒子宽度和高度会加上设置的边框和内边距值。这意味着当你调整一个元素的宽度和高度时需要时刻注意到这个元素的边框和内边距。当我们实现响应式布局时,这个特点尤其烦人。
box-sizing 属性可以被用来调整这些表现:
content-box
是默认值。如果你设置一个元素的宽为100px,那么这个元素的内容区会有100px 宽,并且任何边框和内边距的宽度都会被增加到最后绘制出来的元素宽度中。尺寸计算公式:
width
= 内容的宽度height
= 内容的高度
border-box
告诉浏览器:你想要设置的边框和内边距的值是包含在width内的。也就是说,如果你将一个元素的width设为100px,那么这100px会包含它的border和padding,内容区的实际宽度是width减去(border + padding)的值。大多数情况下,这使得我们更容易地设定一个元素的宽高。尺寸计算公式:
width
= border + padding + 内容的宽度height
= border + padding + 内容的高度
来源:https://developer.mozilla.org/zh-CN/docs/Web/CSS/box-sizing (opens new window)
# 3.6 盒子内容区(content)
CSS属性名 | 功能 | 属性值 |
---|---|---|
width | 设置内容区域宽度 | 长度 |
max-width | 设置内容区域的最大宽度 | 长度 |
min-width | 设置内容区域的最小宽度 | 长度 |
height | 设置内容区域的高度 | 长度 |
max-height | 设置内容区域的最大高度 | 长度 |
min-height | 设置内容区域的最小高度 | 长度 |
- 注意:
max-width、min-width 一般不与 width 一起使用。
max-height、min-height 一般不与 height一起使用。
# 3.7 盒子内边距(padding)
CSS 属性名 | 功能 | 属性值 |
---|---|---|
padding-top | 上内边距 | 长度 |
padding-right | 右内边距 | 长度 |
padding-bottom | 下内边距 | 长度 |
padding-left | 左内边距 | 长度 |
padding | 复合属性 | 长度,可以设置^1 ~^4 个值 |
padding复合属性的使用规则:
- padding: 10px; 四个方向内边距都是 10px。
- padding: 10px 20px; 上10px,左右20px 。(上下、左右)
- padding: 10px 20px 30px; 上10px,左右20px,下30px。(上、左右、下)
- padding: 10px 20px 30px 40px; 上10px,右20px,下30px,左40px。(上、右、 下、左)
- 注意点:
- padding 的值不能为负数。
- 行内元素 的 左右内边距是没问题的,上下内边距不能完美的设置。
- 块级元素 、 行内块元素 ,四个方向 内边距 都可以完美设置。
# 3.8 盒子边框(border)
CSS 属性名 | 功能 | 属性值 |
---|---|---|
border-style | 边框线风格 复合了四个方向的边框风格 | none: 默认值 solid: 实线 dashed: 虚线 dotted: 点线 double: 双实线 |
border-width | 边框线宽度 复合了四个方向的边框宽度 | 长度,默认3px |
border-color | 边框线颜色 复合了四个方向的边框颜色 | 颜色,默认黑色 |
border | 复合属性 | 值没有顺序和数量要求。 |
border-left border-left-style border-left-width border-left-color border-right border-right-style border-right-width border-right-color border-top border-top-style border-top-width border-top-color border-bottom border-bottom-style border-bottom-width border-bottom-color | 分别设置各个方向的边框 | 同上 |
边框相关属性共 20 个。
border-style 、border-width、border-color其实也是复合属性。
- 边框外轮廓
CSS 属性名 | 功能 | 属性值 |
---|---|---|
outline-width | 外轮廓的宽度 | 像素 |
outline-color | 外轮廓的颜色 | |
outline-style | 外轮廓的风格 | none : 无轮廓 dotted : 点状轮廓 dashed : 虚线轮廓 solid : 实线轮廓 double : 双线轮廓 |
outline-offset | 设置外轮廓与边框的距离,正负值都可以设置 |
注意: outline-offset 不是 outline 的子属性,是一个独立的属性。
- outline 复合属性
outline:50px solid blue;
1
# 3.9 盒子外边距(margin)
CSS 属性名 | 功能 | 属性值 |
---|---|---|
margin-left | 左外边距 | CSS中的长度值 |
margin-right | 右 外边距 | CSS中的长度值 |
margin-top | 上 外边距 | CSS中的长度值 |
margin-bottom | 下 外边距 | CSS中的长度值 |
margin | 复合属性,可以写1~4个值,规律同padding(顺时针) | CSS中的长度值 |
# 3.9.1 margin 注意事项
1. 子元素的margin,是参考父元素的content计算的。(因为是父亲的content中承装着
子元素)
2. 上margin、左margin:影响自己的位置;下margin、右margin:影响后面兄弟元素
的位置。
3. 块级元素、行内块元素,均可以完美地设置四个方向的margin;但行内元素,左右
margin可以完美设置,上下margin设置无效。
4. margin的值也可以是 auto,如果给一个 块级元素 设置左右margin都为 auto,该块级
元素会在父元素中水平居中。
5. margin的值可以是负值。
2
3
4
5
6
7
8
9
# 3.9.2 margin 塌陷问题
什么是 margin 塌陷?
第一个子元素的 上 margin会作用在父元素上,父子嵌套的元素垂直方向的margin取最大值。
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>123</title>
<style>
/*
1 不注销掉margin-top 和margin-left,父子嵌套的元素垂直方向的margin取最大值,例子中即margin-top取最大者
2 注销掉margin-top 和margin-left,子元素设置的高度会作用于父元素
*/
.outer{
<!
margin-top:100px;
margin-left: 100px;
width: 300px;
height: 300px;
background-color: antiquewhite;
}
.inner{
margin-top: 50px;
margin-left:50px;
width: 100px;
height: 100px;
background-color: aquamarine;
}
</style>
</head>
<body>
<div class="outer">
<div class="inner"></div>
</div>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
如何解决 margin 塌陷?
方案一: 给父元素设置不为 0 的padding。
方案二: 给父元素设置宽度不为 0 的border。
方案三: 给父元素设置 css 样式 overflow:hidden
2
3
# 3.9.3 margin 合并问题
什么是 margin 合并?
上面兄弟元素的 下外边距 和下面兄弟元素的 上外边距 会合并,取一个最大的值,而不是相加。
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>123</title>
<style>
.outer{
width: 300px;
height: 300px;
background-color: antiquewhite;
}
.inner{
margin-top: 50px;
margin-bottom:50px;
width: 100px;
height: 100px;
background-color: aquamarine;
}
</style>
</head>
<body>
<div class="outer">
<div class="inner"></div>
<div class="inner inner2"></div>
</div>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
如何解决 margin 塌陷?
无需解决,布局的时候上下的兄弟元素,只给一个设置上下外边距就可以了。
# 4. 盒子布局计算问题
# 4.1 盒子水平布局计算
元素的水平方向的布局:
元素在其父元素中水平方向的位置由以下几个属性共同决定“
margin-left
border-left
padding-left
width
padding-right
border-right
margin-right
一个元素在其父元素中,水平布局必须要满足以下的等式
margin-left+border-left+padding-left+width+padding-right+border-right+margin-right = 其父元素内容区的宽度 (必须满足)
- 以上等式必须满足,如果相加结果使等式不成立,则称为过度约束,则等式会自动调整
- 调整的情况:
- 如果这七个值中没有为 auto 的情况,则浏览器会自动调整margin-right值以使等式满足
- 这七个值中有三个值可以设置为auto:
width
margin-left
maring-right
- 如果某个值为auto,则会自动调整为auto的那个值以使等式成立
- 如果将一个宽度和一个外边距设置为auto,则宽度会调整到最大,设置为auto的外边距会自动为0
- 如果将三个值都设置为auto,则外边距都是0,宽度最大
- 如果将两个外边距设置为auto,宽度固定值,则会将外边距设置为相同的值
所以我们经常利用这个特点来使一个元素在其父元素中水平居中
示例:
width:xxxpx;
margin:0 auto;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 4.2 盒子垂直布局计算
默认情况下父元素的高度被内容撑开,子元素是在父元素的内容区中排列的,
如果子元素的大小超过了父元素,则子元素会从父元素中溢出
使用 overflow 属性来设置父元素如何处理溢出的子元素
可选值:
visible,默认值 子元素会从父元素中溢出,在父元素外部的位置显示
hidden 溢出内容将会被裁剪不会显示
scroll 生成两个滚动条,通过滚动条来查看完整的内容
auto 根据需要生成滚动条
常用 overflow:hidden 和 overflow: auto
2
3
4
5
6
7
8
9
10
# 5.居中布局方法
- 行内元素、行内块元素,可以被父元素当做文本处理。
即:可以像处理文本对齐一样,去处理:行内、行内块在父元素中的对齐。
例如:text-align、line-height、text-indent等。
如何让子元素,在父亲中 水平居中 :
- 若子元素为 块元素 ,给子元素设置宽度并加上:margin:0 auto;。
- 若子元素为 行内元素 、 行内块元素 ,给父元素加上:text-align:center。
如何让子元素,在父亲中 垂直居中 :
- 若子元素为 块元素:
给子元素加上:margin-top,值为:(父元素content-子元素盒子总高) / 2 。 - 若子元素为 行内元素 、 行内块元素 :
让父元素的height = line-height,每个子元素都加上:vertical-align:middle;。补充:若想绝对垂直居中,父元素font-size设置为 0 。
让子元素,在父亲中 水平居中,若子元素为 块元素
<!doctype html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>123</title> <style> .outer{ width: 300px; height: 300px; background-color: antiquewhite; } .inner{ margin:0 auto; width: 100px; height: 100px; background-color: aquamarine; vertical-align: middle; } </style> </head> <body> <div class="outer"> <div class="inner"></div> </div> </body> </html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30让子元素,在父亲中 水平居中,若子元素为 行内元素 、 行内块元素
<!doctype html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>123</title> <style> .outer{ width: 300px; height: 300px; background-color: antiquewhite; text-align: center; } .inner{ display: inline-block; width: 100px; height: 100px; background-color: aquamarine; vertical-align: middle; } </style> </head> <body> <div class="outer"> <div class="inner"></div> </div> </body> </html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30让子元素,在父亲中 垂直居中,若子元素为 块元素
<!doctype html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>123</title> <style> .outer{ width: 300px; height: 300px; background-color: antiquewhite; overflow: hidden; } .inner{ margin-top:calc((300px - 100px)/2); width: 100px; height: 100px; background-color: aquamarine; vertical-align: middle; } </style> </head> <body> <div class="outer"> <div class="inner"></div> </div> </body> </html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32让子元素,在父亲中 垂直居中,若子元素为 行内元素 、 行内块元素
<!doctype html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>123</title> <style> .outer{ width: 300px; height: 300px; background-color: antiquewhite; /* overflow: hidden; */ line-height: 300px; } .inner{ /* margin-top:calc((300px - 100px)/2); */ display: inline-block; width: 100px; height: 100px; background-color: aquamarine; vertical-align: middle; } </style> </head> <body> <div class="outer"> <div class="inner"></div> </div> </body> </html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36- 若子元素为 块元素:
# 6. 处理内容溢出
CSS 属性名 | 功能 | 属性值 |
---|---|---|
overflow | 溢出内容的处理方式 | visible:显示,默认值 hidden:隐藏 scroll:显示滚动条,不论内容是否溢出 auto:自动显示滚动条,内容不溢出不显示 |
overflow-x | 水平方向溢出内容的处理方式 | 同 overflow |
overflow-y | 垂直方向溢出内容给的处理方式 | 同^ overflow |
- 注意:
1. overflow-x 、 overflow-y 不能一个是hidden,一个是visible,是实验性属性,不建议使用。 2. overflow 常用的值是 hidden和 auto,除了能处理溢出的显示方式,还可以解决很多疑难杂症。
1
2
# 7. 元素之间的空白问题
产生的原因:
行内元素、行内块元素,彼此之间的换行会被浏览器解析为一个空白字符。
解决方案:
方案一: 去掉换行和空格(不推荐)。
方案二: 给父元素设置 font-size:0,再给需要显示文字的元素,单独设置字体大小(推荐)。
<!doctype html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>123</title> <style> .outer{ width: 300px; height: 300px; background-color: antiquewhite; text-align: center; /* 解决方案 */ /* font-size: 0; */ } .inner{ display: inline-block; width: 100px; height: 100px; background-color: aquamarine; vertical-align: middle; } .inner2{ background-color: blueviolet; } </style> </head> <body> <div class="outer"> <div class="inner"></div> <div class="inner inner2"></div> </div> </body> </html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 8. 行内块的幽灵空白问题
产生原因:
行内块元素与文本的基线对齐,而文本的基线与文本最底端之间是有一定距离的。
解决方案:
- 方案一: 给行内块设置vertical ,值不为 baseline 即可,设置为 middel、bottom、top 均可。
- 方案二: 若父元素中只有一张图片,设置图片为 display:block。
- 方案三: 给父元素设置 font-size: 0。如果该行内块内部还有文本,则需单独设置font-size。
<!doctype html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>123</title> <style> .outer{ width: 300px; background-color: antiquewhite; /* 解决方案 */ /* font-size: 0; */ } .inner{ display: inline-block; width: 100px; height: 100px; background-color: aquamarine; } </style> </head> <body> <div class="outer"> <div class="inner"></div> </div> </body> </html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32- 效果
# 9. 隐藏元素的方式
# 方式一:visibility 属性
visibility 属性默认值是 show,如果设置为 hidden,元素会隐藏。
元素看不见了,还占有原来的位置(元素的大小依然保持)。
# 方式二: display 属性
设置 display:none,就可以让元素隐藏。
彻底地隐藏,不但看不见,也不占用任何位置,没有大小宽高。