CSS盒模型

  • 基本概念: 标准模型 + IE 模型
  • 标准模型和IE模型的区别
  • CSS 如何设置这俩种模型
  • JS 如何设置获取盒模型对应的宽和高
  • 实例 (根据盒模型解释边距重叠)
  • BFC (边距重叠的解决方案)

1.基本概念

CSS盒模型本质上是一个盒子,封装周围的HTML元素,它包括:边距,边框,填充,和实际内容。

盒子一共有四部分:

  • Margin(外边距) - 清除边框外的区域,外边距是透明的。(虽然margin不是盒子宽度 但却占用 像素)
  • Border(边框) - 围绕在内边距和内容外的边框。
  • Padding(内边距) - 清除内容周围的区域,内边距是透明的。
  • Content(内容) - 盒子的内容,显示文本和图像。

根据浏览器的不同将盒子模型分为俩种: 标准模型和IE模型

2.标准模型和IE模型的区别

在做出区别之前我们在这里先了解CSS盒子模型是怎么计算的!

示例子:

1
2
3
4
5
6
div {
width: 300px;
border: 25px solid green;
padding: 25px;
margin: 25px;
}

CSS盒子的总宽度 = 内容宽度 + 填充宽度 + 边框宽度 + 外边框宽度;

CSS盒子的总宽度计算公式 = width + padding-left + padding-right + border-left + border-right + margin-left + margin-right;

以上面的CSS例子作准:

让我们自己算算:300px (宽) + 50px (左 + 右填充) + 50px (左 + 右边框) + 50px (左 + 右外边距) = 450px

好了我们知道CSS盒子模型的计算方式我们下面来讲述标准模型和IE模型

1.W3C盒子模型(标准盒模型):

img

标准模型的宽度是:content的宽度,不包含padding和border;(内容content是一个独立的部分)

2.IE盒子模型(怪异盒模型):

img

IE模型的宽度是:宽和高是计算 border 和 padding 的

计算方式:width + border + padding

3.CSS 如何设置这俩种模型

1
2
box-sizing:content-box;(标准模型--浏览器默认)   
box-sizing:border-box;(IE模型--IE浏览器专属)

4.JS 如何设置获取盒模型对应的宽和高

获取盒模型的方式有四种:

1
2
3
4
5
6
7
8
9
10
11
12
1.dom.style.width/height(只能取内联样式的宽和高,支持读写)
----getElementById('div').style.width/height

2.dom.currentStyle.width/height
(渲染之后的宽高--只有IE支持)

3.window.getComputedStyle(dom).width/height
(渲染之后的宽高--兼容性通用型更好一些,包括了内联样式、嵌入样式和外部样式,支持读取但不支持写入)

4.dom.getBoundingClientRect().width/height
(适用场景:计算一个元素的绝对位置;这个绝对位置根据视窗
也就是左上角这个位置的绝对位置) 这个方法可以拿到四个元素:left top width height)

5.根据盒模型解释边距重叠

1.父子元素边距重叠

已知子元素高度为100px,距父元素顶部10px,计算父元素的高度?

  1. 因为父元素和子元素存在边距重叠(margin-top),所以父元素高度为100px;
  2. 父元素设置了overflow:hidden;之后父元素高度为110px;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<style>
*{margin: 0; padding: 0;}
.parent{
background: blue; /*若是不加overflow则父背景与子背景重叠,被覆盖*/
/* overflow: hidden; 父子元素边距重叠 */
}

.child{
height: 100px;
margin-top: 10px;
background: red;
}
</style>
<body>
<section class='parent'>
<article class='child'></article>
</section>
</body>

overflow:hidden; 解决了重叠问题;相当于给父元素创建了一个BFC(块级格式化上下文,后面会讲)

2.兄弟元素重叠

若是兄弟元素都存在上边距或者下边距,发生重叠则取最大值;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<body>
<style>
*{margin: 0; padding: 0;}
.brother1{
height: 100px;
margin-bottom: 20px; /*与下面的元素重叠,20px较10px大则取最大值*/
background: blue;
}

.brother2{
height: 100px;
margin-top: 10px;
background: red;
}
</style>

<section class='brother1'></section>
<section class='brother2'></section>
</body>

borther1元素下边距为20px,下面那个brother2元素上边距为10px,因此发生了重叠,根据两者之间取最大值则会合并成20px。大多数边距重叠都会发生在兄弟重叠。

3.空元素

如果一个无内容空元素设置上下边距,其自身上下边距也会产生重叠,从margin-top\margin-bottom取一个最大值,作为它的一个边距。

6.BFC (边距重叠的解决方案)

BFC是块级元素格式化上下文,IFC是内联元素格式化上下文。

BFC的原理(渲染规则):

  1. 在BFC这个元素的垂直方向的边距会发生重叠
  2. BFC的区域不会与浮动元素的相重叠(清除浮动布局)
  3. BFC在页面是一个独立的容器,外面的元素不会影响它里面元素,反过来一样
  4. 计算BFC高度的时候浮动元素也会参与计算

如何创建BFC?

  • overflow 不为 visible
  • float值不为 none(只要有浮动,当前元素就创建了BFC)
  • position不为 static 和relative
  • display为 inline-block, table-cell, table-caption, flex, inline-flex

BFC使用场景

  1. 在写页面布局的时候不想有这个重叠,就给子元素增加一个父元素,父元素创建一个BFC就能解决问题;
  2. 布局相关的BFC应用:

应用1:BFC垂直方向边距重叠

垂直方向三个p元素,p{margin:5px auto 25px},之后第二个第三个的上边距变成25px;发生了边距重叠,取得的是最大值;如果不想重叠,就需要再那个元素在加一个父级div,对父级div创建BFC(overflow:hidden)

应用2:BFC不与float重叠

两栏布局,左边宽度固定左浮动height:100px,右边自适应height:120px;右边的高度增高的时候,右边的背景色已经侵染到了左侧,(当布局的时候左侧没有float元素,它依然会往左侵染),解决方法:给右侧元素创建一个BFC(overflow:atuo)

应用3:清除浮动;(BFC子元素即使是float元素也会参与计算)

1
2
3
4
5
6
7
8
9
10
11
.layout{background:orange}
.float{float:left;}

---->只看到.float的内容没看到父级的背景颜色;父级高度为0
---->一个普通的元素当子元素是float元素的时候,它的高度计算没有包含进来;

.layout{background:orange;overflow:hidden;}
.float{float:left;}

---->给layout设置BFC之后,float内容有了背景颜色,父级有了高度;
---->当把外层元素设为BFC的时候,子元素的浮动元素也会参与父级的高度计算;

演示代码:

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

<body>
<style>
*{margin: 0;padding: 0;}
</style>
<!-- 1.BFC 垂直方向边距重叠 -->
<section id="margin">
<style>
#margin{
background: palegoldenrod;
overflow: hidden;
}
#margin>p{
margin-bottom: 45px;
background: red;
border: 1px solid blue;
}
</style>
<p>1</p>
<div style="overflow: hidden;"> <!-- 不产生边距重叠 -->
<p>2</p>
</div>
<p>3</p>
</section>

<!--2.BFC 不与float重叠 -->
<section id="layout">
<style>
#layout{
background: red;
}
#layout .left{
float: left;
width: 100px;
height: 100px;
background: pink;
}
#layout .right{
height: 110px;
background: #ccc;
overflow: auto;
}
</style>

<div class="left"></div>
<div class="right"></div>
</section>

<!-- 3.BFC 子元素即使是float也会参与高度计算 -->
<section id="float">
<style>
#float{
background: red;
overflow: auto;
/* float: left; */
}
#float .float{
float: left;
font-size: 30px;
}
</style>
<div class="float">我是浮动元素</div>
</section>
</body>

应用4:BFC的元素在计算高度的时候会考虑内部子元素float
(子元素是float也不影响父元素高度的计算,它的内容页会被参与进来)