这一篇来说明一下css当中一些bug,这两个bug出现在margin属性上面,分别是margin合并和margin塌陷
margin合并
首先我们理解一下margin的正常效果,比如下面的例子,我们通过margin让两个元素隔开
<span class="left">我在左边</span>
<span class="right">我在右边</span>
.left{
color: red;
margin-right: 20px;
}
.right{
color: green;
margin-left: 20px;
}
/* 这样设置之后,他们之间的间距应该是 20px + 20px = 40px */
当然显示出来的样子和我们预期的是一样的!
那么margin合并出现在什么地方呢?那么我们来看一下上下布局的时候,这里的margin的情况
<div class="top">我在上面</div>
<div class="bottom">我在下面</div>
.top{
width: 100px;
height: 100px;
background: red;
margin-bottom: 100px;
}
.bottom{
width: 100px;
height: 100px;
background: green;
margin-top: 100px;
}
/*理论上我们看到的应该是两个div上下相隔200px*/
但是实际上和我们猜测的有点出入,它们这里的div的高度是100px
所以什么是margin合并呢?
兄弟结构水平方向的margin正常,但是垂直方向上面的margin会合并,并且这里的取到的是较大的一个,一般情况下,margin合并我们可以不处理,合理安排垂直方向的margin就能达到需求效果。
margin塌陷
父子结构的元素,垂直方向上的margin,会取最大那个
<div class="box">
<div class="wrapper">
<div class="content"></div>
</div>
</div>
.box{
width: 300px;
height: 300px;
border: 1px solid #ccc;
}
.wrapper {
width: 100px;
height: 100px;
background: #000;
margin-top: 50px;
margin-left: 50px;
}
.content {
margin-left: 100px;
/*margin-top: 100px;*/
width: 50px;
height: 50px;
background: orange;
}
根据上面代码,我们先将margin-top给注释掉,看一下结果
我们可以看到,我们的黄色方块根据黑色方块向左移动了100px,这样可以理解,很正常,但是当我们将注释的代码打开的时候,根据上面的经验我们应该看到的是黄色的方块到了黑色的方块的对角线的下方。
显然这里出现出乎预料的问题,就是我们的黄色的方块带着黑色方块向下移动了50px,当然这就是margin塌陷的问题了,感觉我们的黑色的盒子在垂直方向上面好像不能够作为margin对应的参照物了,好像头顶是空的,这就是取名margin塌陷的原因。其实这里的margin的算法是这样的==他们的两个的margin会根据较大的一个取==,也就是父子在水平方向上,谁大听谁的,而且是相对有头顶的元素
先了解一下BFC
BFC: block format context - 块级格式化上下文,每一个盒子当中都有一套正常的渲染规则,但是我们可以通过一些语法,来触发bfc,让这个盒子的渲染规则不一样! 就是这个渲染规则的改变,刚好就解决了margin塌陷的问题,下面是触发bfc的语法:
- position: absolute;
- display:inline-block;
- float:left / right
- overflow: hidden;
margin塌陷的解决方案
- 给父级元素,上面的黑色盒子,加一个头顶,直接使用border-top来处理,但是这样会带来更多的问题,多了的border像素影响也是不小的。
- 使用overflow:hidden;来触发bfc来解决,overflow:hidden;自己也有自己的含义,
溢出部分隐藏
,这个方法有个缺点就是,假如我们有使用js来更换子元素的位置的时候,一旦出了盒子,就不能显示了 - 其他触发bfc的方法
如上的方案我们根据实际情况来选择,比如假如父级元素刚好就要加边框,那么我们就刚好可以选择第一种方法,根据需求合理的选择。
使用bfc来处理margin合并,高端一下
其实我们可以使用bfc来处理margin合并的情况,给两个元素或者其中一个元素加上一个父级元素,并让父级元素触发bfc
<div class="box">
<div class="top"></div>
</div>
<div class="box">
<div class="bottom"></div>
</div>
.box{
overflow: hidden;
}
.top {
width: 100px;
height: 100px;
background-color: red;
margin-bottom: 100px;
}
.bottom {
width: 100px;
height: 100px;
background-color: green;
margin-top: 100px;
}
处理好的结果:
但是这种方法是不推荐的,主动去改变html结构是很不理想的做法!!!