其实css也不是极其完善的,其中也存在着或多或少的bug,有些我们可能从来不会遇到,有些我们可能会经常遇到,这次介绍的两个bug是属于cssbug中的很经典的两个bug——margin合并与margin塌陷问题。
margin合并现象
• 我们现在写两个span标签,并且给它们两个分别加上margin-right和margin-left的样式。
<span class=”left”>left</span>
<span class=”right”>right</span>
1. .left {
2. margin-right: 10px;
3. background-color: red;
4. }
5. .right {
6. margin-left: 10px;
7. background-color: yellow;
8. }
我们会发现,这两个span之间的距离正是我们所想的那样是20px的宽度,但是我们现在再写两个div,然后分别给它们加上margin-bottom和margin-top的样式,我们再来看看效果。
<div class=”top”>top</div>
<div class=”bottom”>bottom</div>
1. .top {
2. margin-bottom: 10px;
3. background-color: red;
4. }
5. .bottom {
6. margin-top: 10px;
7. background-color: yellow;
8. }
这次我们惊奇的发现,这两个div上下之间的距离,并不是我们所想的那样是相加的20px,而是只有10px!
这个现象就是标题所说的margin上下合并现象。
我们尝试改变每一个div的margin-top或者margin-bottom的值,最后发现:二者上下之间的距离是取得两个数值之中的最大值。
如果div.top的margin-bottom是100px,div.bottom的margin-top是50px的话,那么二者之间的距离就是100px。
margin塌陷现象
• 当我们给这样一个结构的两个div分别设置margin-top的时候,这个bug就会出现了。
<div class=”wrapper”>
<div class=”content”></div>
</div>
1. .wrapper {
2. width: 100px;
3. height: 100px;
4. margin-top: 100px;
5. margin-left: 100px;
6. background-color: yellow;
7. }
8.
9. .content {
10. width: 50px;
11. height: 50px;
12. margin-top: 50px;
13. margin-left: 50px;
14. background-color: red;
15. }
我们写这段代码的原意是想要一个100100大小的父级div,然后里面有一个5050大小的子级div,然后让这个div在父级div的右下角,同时父级div距离浏览器的边框有100px的距离。
当我们运行这段代码的时候,我们会发现,实际的结果是这个样子的:
子级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塌陷现象。
那么对于这两个问题我们要怎么解决呢?
margin塌陷的解法
解法一共有两种:
1.利用border来触发bfc的效果。
2.利用overflow属性来触发bfc的效果。
• 那么什么是bfc呢?
bfc全称是block format context——块级格式化上下文,我们有一些css语法会触发bfc,从而带来的效果是我们触发bfc的元素的渲染规则和普通元素的渲染规则变得不一样,从而可以解决塌陷问题。
margin塌陷的问题很容易让我们联想到,子级div之所以没有相对父级移动,是因为它看不到父级的边界,只能看到浏览器的边界,这样我们给父级加一个子级能看到的边界,这个问题是不是就解决了?
所以我们在父级div.wrapper里面添加一个属性:border-top: 1px solid red;现在我们再来看一下效果,发现果然content和wrapper解除了绑定,子级div能看到父级的边界了。但是这样就会改变父级div的样式,不符合开发要求,因此这种方法虽然可以解决问题但是是完全无法使用的。
• 什么又是overflow呢?
overflow是一个css属性,它可以设置当内容区超过了当前元素的区域的时候,我们采取怎样的处理方式,这个属性也可以触发bfc。
现在我们可以在父级div.wrapper里面加一条属性:overflow:hidden;这条属性的意思是溢出隐藏。现在我们可以发现,在外观没有改变的同时,子级div和父级div解除了绑定,也可能正常移动了!因此我们一般采用这种方式来解决margin塌陷的问题。
虽然overflow:hidden;的方式可以采用,但是也不是没有缺点的,一旦我们用过js代码改变了子级div的位置,就会有导致子级一部分内容因为溢出被隐藏的风险。
margin合并的解法
了解了margin塌陷的解法之后,我们就很容易可以理解margin合并的解法了。
我们给每一个div分别加上一个父级包裹层,然后给父级包裹层都加上overflow:hidden;
<div class=”wrapper”>
<div class=”top”>top</div>
</div>
<div class=”wrapper”>
<div class=”bottom”>bottom</div>
</div>
1. .wrapper{
2. overflow: hidden;
3. }
4. .top {
5. margin-bottom: 100px;
6. background-color: red;
7. }
8. .bottom {
9. margin-top: 100px;
10. background-color: red;
11. }
这样通过父级div来触发bfc就可以解决margin合并的问题了。
那么今天的东西就这么多,希望对大家有所帮助哟~