1. 外边距折叠
垂直方向上的两个外边距相遇时,会折叠成一个外边距,折叠后的外边距高度等于两者中的较大值。
外边距折叠发生条件
外边距折叠存在两种情况
- 兄弟外边距折叠
以下情况会发生外边距折叠
<div class="container">
<div>
<div class="block top"></div>
</div>
<div class="block bottom"></div>
</div>
- 父子外边距折叠
消除外边距折叠方法
行内盒子、浮动盒子或绝对定位盒子的外边距不会折叠。
- 外边距不采用两个相加的形式,直接设置其中一个。
- 根据BFC(block formatting context)块级格式化上下文来阻止外边距折叠。
2. BFC
BFC(Block fomatting context)是一个独立的布局环境,其中的元素布局是不受外界的影响,也不会影响外界,并且在一个BFC中,块盒与行盒(行盒由一行中所有的内联元素所组成)都会垂直的沿着其父元素的边框排列。
BFC的创建
- float的值不是none
- position的值不是static或者relative
- display的值是inline-block、table-cell、flex、table-caption或者inline-flex
- overflow的值不是visible
BFC的用途
- 清除元素内部浮动
只要把父元素设为BFC就可以清理子元素的浮动了,最常见的用法就是在父元素上设置overflow: hidden样式,对于IE6加上zoom:1就可以了。 - 解决外边距折叠
属于同一个BFC的两个相邻盒子的margin会发生重叠,那么我们创建不属于同一个BFC,就不会发生margin重叠了。
运行下面代码看结果,外边距不会发生合并
<!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>防止margin折叠</title>
</head>
<style>
*{
margin: 0;
padding: 0;
}
p {
color: #f55;
background: pink;
width: 200px;
line-height: 100px;
text-align:center;
margin: 30px;
}
div{
overflow: hidden; /*这里新建了一个BFC*/
}
</style>
<body>
<p>看看我margin</p>
<div>
<p>看看我的 margin</p>
</div>
</body>
</html>
- 自适应两栏布局
普通流体元素形成BFC后,不会与浮动元素有任何交集,顺着浮动边缘形成自己的封闭上下文。
<!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>
</head>
<style>
*{
margin: 0;
padding: 0;
}
body {
width: 100%;
position: relative;
}
.left {
width: 100px;
height: 150px;
float: left;
background: orange;
text-align: center;
line-height: 200px;
font-size: 20px;
}
.right {
overflow: hidden; /*看这里!看这里!划重点!划重点!*/
height: 300px;
background: green;
text-align: center;
line-height: 300px;
font-size: 40px;
}
</style>
<body>
<div class="left">LEFT</div>
<div class="right">RIGHT</div>
</body>
</html>
如果以上代码 right 类中没有 overflow: hidden;,是下面的效果
现在的效果:
3. inline-block 的间距
将 display 设置为 inline-block 是创建BFC的其中一种方式,但这种布局会存在一个4px左右的的间隙。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>inline-block</title>
<style type="text/css">
.container a{
display: inline-block; /*看这里!看这里!看这里!*/
background-color: orange;
padding: 6px;
}
</style>
</head>
<body>
<div class="container">
<a href="#">一</a>
<a href="#">二</a>
<a href="#">三</a>
<a href="#">四</a>
</div>
</body>
</html>
运行后见下图:
解决方法
- 可以在html中直接把元素写在一行上 或 把闭合标签和第二个开始标签写在一行 或 两行间添加注释或直接去掉闭合标签但最后一个不能去掉。
<div class="container">
<a href="#">一<a href="#">二<a href="#">三<a href="#">四</a>
</div>
- 设置 margin-right 为负值,但要考虑上下文的字体和文字大小。
.container a{
display: inline-block;
background-color: orange;
padding: 6px;
margin-right: -5px; /*看这里!看这里!看这里!*/
}
运行后如下图: