margin塌陷
<div class=”wrapper”>
<div class=”content”></div>
</div>
.wrapper {
width: 100px;
height: 100px;
margin-top: 100px;
margin-left: 100px;
background-color: yellow;
}
.content {
width: 50px;
height: 50px;
margin-top: 50px;
margin-left: 50px;
background-color: red;
}
上述例子想要得到的结果应该是在大的100*100得div中有一个50*50的div,这个小的div应该是在大的div的右下角:
但我们得到的结果却是:
子级div的margin-left生效了但是好像margin-top并没有生效?
其实并不是,margin-top也生效了,但是这里的margin-top的效果并不是我们所想的那样距离父级div的距离是50px,而是子级的div距离浏览器边框的距离是50px,由于本身父级div有一个margin-top的值,所以就导致了我们子级的margin-top的效果并没有显现出来,我们再改变一下子级div的margin-top的值,改成200px,我们又会惊奇的发现,子级div不仅没有距离父级div有了一段距离,反而带动了父级div一起向下移动了!这就是margin塌陷现象。
解决办法:
1.利用border来触发bfc的效果。
2.利用overflow属性来触发bfc的效果。
在这儿,我们就不得不说一说bfc了。
bfc全称是block format context——块级格式化上下文,他是一个独立的布局环境,其中的元素布局是不受外界的影响,并且在一个BFC中,块盒与行盒(行盒由一行中所有的内联元素所组成)都会垂直的沿着其父元素的边框排列。我们有一些css语法会触发bfc,从而带来的效果是我们触发bfc的元素的渲染规则和普通元素的渲染规则变得不一样,从而可以解决塌陷问题。
能生成bfc的元素:
根元素
float属性不为none
position为absolute或fixed
display为inline-block, table-cell, table-caption, flex, inline-flex
overflow不为visible
margin塌陷的问题很容易让我们联想到,子级div之所以没有相对父级移动,是因为它看不到父级的边界,只能看到浏览器的边界,这样我们给父级加一个子级能看到的边界,这个问题是不是就解决了?所以我们在父级div.wrapper里面添加一个属性:border-top: 1px solid red;现在我们再来看一下效果,发现果然content和wrapper解除了绑定,子级div能看到父级的边界了。但是这样就会改变父级div的样式,不符合开发要求,因此这种方法虽然可以解决问题但是是完全无法使用的。
所以一般我们会用overflow的方式来解决。
overflow是一个css属性,它可以设置当内容区超过了当前元素的区域的时候,我们采取怎样的处理方式,这个属性也可以触发bfc。
现在我们可以在父级div.wrapper里面加一条属性:overflow:hidden;这条属性的意思是溢出隐藏。现在我们可以发现,在外观没有改变的同时,子级div和父级div解除了绑定,也可能正常移动了!
虽然overflow:hidden;的方式可以采用,但是也不是没有缺点的,一旦我们用过js代码改变了子级div的位置,就会有导致子级一部分内容因为溢出被隐藏的风险。
margin合并
当我们给两个div分别加上margin-bottom和margin-top的样式时,我们会发现,他们之间的距离并不是两个margin相加,而是取了他们当中的最大值,eg:
<div class=”top”></div>
<div class=”bottom”></div>
.top {
margin-bottom: 10px;
background-color: red;
}
.bottom {
margin-top: 10px;
background-color: yellow;
}
这两个div上下之间的距离,并不是我们所想的那样是相加的20px,而是只有10px。
解决办法:
了解了margin塌陷的解法之后,我们就很容易可以理解margin合并的解法了。
我们给每一个div分别加上一个父级包裹层,然后给父级包裹层都加上overflow:hidden;这样通过父级div来触发bfc就可以解决margin合并的问题了。
<div class=”wrapper”>
<div class=”top”></div>
</div>
<div class=”wrapper”>
<div class=”bottom”></div>
</div>
.wrapper {
overflow: hidden;
}
.top {
margin-bottom: 100px;
background-color: red;
}
.bottom {
margin-top: 100px;
background-color: red;
}