所有HTML元素可以看作盒子,在CSS中,box model
这一术语是用来设计和布局时使用。
CSS盒模型本质上是一个盒子,封装周围的HTML元素,它包括:边距
,边框
,填充
,和实际内容
。
盒模型允许我们在其它元素和周围元素边框之间的空间放置元素。
下面的图片说明了盒子模型(Box Model):
不同部分的说明:
- Margin(外边距) - 清除边框外的区域,外边距是透明的。
- Border(边框) - 围绕在内边距和内容外的边框。
- Padding(内边距) - 清除内容周围的区域,内边距是透明的。
- Content(内容) - 盒子的内容,显示文本和图像。
- 注意:我们用盒子的宽高来衡量盒子的大小,可以看做总元素的宽度和高度,和元素本身设置的宽度和高度(width,height)不是同一个概念。
标准盒模型
- 元素的 width、height 只包含内容 content,不包含 border 和 padding 值;
- 盒子的大小由元素的宽高、边框和内边距决定。
- 盒子的宽/高 = width/height + border + padding + margin
模型如下图:IE盒模型
- 元素的 width、height 不仅包括 content,还包括 border 和 padding;
- 盒子的大小取决于 width、height,修改 border 和 padding 值不能改变盒子的大小
- 盒子宽/高=width/height + margin = 内容区宽度/高度 + padding + border + margin
盒型如下图:
兼容
- 标准盒模型和IE盒模型就在内容content的区别,标准盒模型的content只包括width/height,而IE盒模型的content包括width/height+border+padding。
- 标准盒模型下元素的
box-sizing
属性(IE8+)默认值为content-box
,将它设置成border-box
可转换为 IE 盒模型。在实际应用场景中,若想控制元素总宽高保持固定,这个设置很有用。 - 元素的宽(width)、高(height)、边框(border)、内边距(padding)、外边距(margin)都是盒子模型的重要组成部分,但是盒子模型的大小只与元素的宽高、边框、内间距有关,外边距只影响盒子所占外围空间的大小。
边距重叠解决方案(BFC)
首先要明确BFC是什么意思,其全英文拼写为Block Formatting Context
直译为块级格式化上下文
。它是一个独立的渲染区域,只有Block-level box
参与, 它规定了内部的Block-level Box
如何布局,并且与这个区域外部毫不相干。 Block-level box
:display 属性为 block, list-item, table 的元素。inline-level box
:display 属性为 inline, inline-block, inline-table的元素。BFC布局规则
- 内部的box会在垂直方向,一个接一个的放置
- 每个元素的margin box的左边,与包含块border box的左边相接触(对于从做往右的格式化,否则相反)
- box垂直方向的距离由margin决定,属于同一个BFC的两个相邻box的margin会发生重叠
- BFC的区域不会与浮动区域的box重叠
- BFC是一个页面上的独立的容器,外面的元素不会影响BFC里的元素,反过来,里面的也不会影响外面的
- 计算BFC高度的时候,浮动元素也会参与计算
如何创建BFC
- float属性不为none(脱离文档流)
- position为absolute或fixed
- display为inline-block,table-cell,table-caption,flex,inline-flex
- overflow不为visible
- 根元素, 即HTML元素
BFC的作用
- 利用BFC避免margin重叠
- 自适应两栏布局
- 清除内部浮动
例子如下:避免margin重叠
在上面的例子中,margin会重叠,会以最大的margin为准。也就是两个p元素的外边距为30px。1
2
3
4
5
6
7
8
9
10
11
12<style>
.pOne{
margin: 10px 0;
}
.pTwo{
margin: 30px 0;
}
</style>
<body>
<p class="pOne">文本1</p>
<p class="pTwo">文本2</p>
</body>
当我们利用BFC时利用BFC消除了margin重叠问题,这样的话两个p元素的外边距为30+10=40px。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<style>
.pOne{
margin: 10px 0;
}
.pTwo{
margin: 30px 0;
}
div{
overflow: hidden;
}
</style>
<body>
<p class="pOne">文本1</p>
<div >
<p class="pTwo">文本2</p>
</div>
</body>自适应两栏布局
根据BFC的布局规则:每个元素的margin box的左边,与包含块border box的左边相接触(对于从做往右的格式化,否则相反)。效果如下图: 根据BFC的布局规则:BFC的区域不会与浮动区域的box重叠。所以我们要创建一个BFC,避免left和right重叠。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16<style>
.left{
height: 300px;
width: 200px;
background-color: #00FFFF;
float: left;
}
.right{
height: 500px;
background-color: #F5F5DC;
}
</style>
<body>
<div class="left">LEFT</div>
<div class="right">RIGHT</div>
</body>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<style>
.left{
height: 300px;
width: 200px;
background-color: #00FFFF;
float: left;
}
.right{
height: 500px;
overflow: hidden; /*right变为BFC*/
background-color: #F5F5DC;
}
</style>
<body>
<div class="left">LEFT</div>
<div class="right">RIGHT</div>
</body>清除内部浮动
当我们不给父节点设置高度,子节点设置浮动的时候,会发生高度塌陷,这个时候我们就要清除浮动。效果如下,父节点高度塌陷: 根据BFC布局规则:计算BFC高度的时候,浮动元素也会参与计算。因此我们把父节点设置为BFC就可以解决高度塌陷。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18<style>
.parent{
width: 300px;
border: 5px solid darkgoldenrod;
}
.child{
height: 100px;
width: 100px;
float: left;
border: 5px solid #00FFFF;
}
</style>
<body>
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>
</body>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19<style>
.parent{
width: 300px;
border: 5px solid darkgoldenrod;
overflow: hidden; /*BFC*/
}
.child{
height: 100px;
width: 100px;
float: left;
border: 5px solid #00FFFF;
}
</style>
<body>
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>
</body>
关于解决父节点高度塌陷问题
给父元素末尾添加一个空元素,并设置成清除浮动
1 | <div style="clear:both;"></div> |
缺点:添加了无意义标签,不易于后期维护,违背了结构和表现分离的标准
给父元素添加 overflow:auto;
让父元素也浮动
缺点:影响整体页面布局,若父元素也有父元素呢?总不能一直浮动到body吧?
使用after伪元素
给父元素添加一个类,来添加一个看不见的块元素,以实现清除浮动。
1 | .clearfix:after |
BFC
也就是BFC的布局规则:计算BFC高度的时候,浮动元素也会参与计算。上面的方法也用到了这条规则。下面这个方法是一个不错的方法。
1 | .clearfix:after, |