美文网首页
外边距重叠

外边距重叠

作者: MigoQY | 来源:发表于2017-06-13 19:48 被阅读0次

学习HTML的时候遇到过这种情况:

两个块级box垂直方向相邻,如果设置它们的上下margin,就会发生重叠(margin塌陷)现象。

当时也没有想太多,只知道有这种情况,在使用的时候会尽量设置单个margin或者设置padding值,来避免出现重叠现象,但闲下来时,我仔细想了下这个问题,然后查询了一些资料,结果引出来一个东西 BFC

BFC

什么是BFC?

要了解什么是BFC,就要涉及一些CSS布局的一些基本概念,其中块级盒的概念要清楚。

盒模型

在W3C规定里,完整的盒模型为:


  • content:内容(主体)
  • padding:内边距
  • border:边框
  • margin:外边距

每个块级元素都会自动生成一个块级盒block-level box,每个块级盒的盒模型结构都如上图盒模型一样。
其中,margin、padding、border、content分别定义了元素的四种边,每种类型的边定义了一种盒子,分别是margin box、padding box、border box 、content box。而控制块级盒之间的垂直间距的就是margin box。
我们对块级元素布局的描述为:

普通流中的块元素独占一行,然后从上往下一个接一个的排布,相邻元素间会有外边距折叠

为什么会是这种布局呢?原因就是BFC的存在

BFC定义

BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。

BFC布局规则(重点)

  • 内部的Box会在垂直方向,一个接一个地放置。
  • Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
  • 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
  • BFC的区域不会与float box重叠。
  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
  • 计算BFC的高度时,浮动元素也参与计算

触发(创建)BFC

  • float的值不为none
  • overflow的值为auto、scroll或hidden。
  • display的值为inline-block, table-cell, table-caption, flex, inline-flex中的任何一个。
  • position的值不为relative和static(可以为absolute或fixed)

BFC功能和作用

1. 自适应左右两栏布局

代码:

     <style>
         html,body{
             width: 100%;
             height: 100%;
         }
       .box1{
           width: 180px;
           height: 300px;
           background-color: purple;
           float: left;
       }
         .box2{
             height: 100%;
             background-color: yellow;
         }
     </style>
<body>
<div class="box1"></div>
<div class="box2"></div>
</body>

显示效果:


根据BFC布局规则:

每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。

因此,即时存在浮动元素box1,但box2的左边依然紧贴父元素左边界。

如何实现左右两栏分布?
根据BFC布局规则:

BFC的区域不会与float box重叠

可以设置box2为BFC,触发BFC效果,实现自适应两栏布局。

.box2{
             height: 100%;
             background-color: yellow;
             overflow: hidden;
         }

当触发box2生成BFC后,这个新的BFC就不会与浮动的box1重叠。因此box2会根据包含块(父元素)的宽度,和box1的宽度,自动变窄(自适应)。效果如下:


清除内部浮动

代码:

     <style>
         html,body{
             width: 100%;
             height: 100%;
         }
         .father{
           width: 200px;
           border:8px solid #d02c38;
         }
         .son{
             width: 80px;
             height: 80px;
             border:5px solid #666666;
             display: inline-block;
             float: left;
         }
     </style>
<body>
<div class="father">
    <div class="son"></div>
    <div class="son"></div>
</div>
</body>

页面显示为:



father盒子中的son盒子全部为浮动后,内容无法撑起父盒子的高度,所以father盒子显示为一条宽度为16px的实线,想撑起父盒子的高度,就需要清除浮动带来的影响。
根据BFC规则:

计算BFC的高度时,浮动元素也参与计算

因此,father元素触发BFC,那么father元素计算高度的时候,会把son元素的高度也计算进去,相当于给father设置了高度,达到清除浮动的效果。


防止垂直重叠

在文章开头就说到,相邻两个块级元素的上下margin值会发生重叠现象。现在可以通过BFC来解决这个问题。
代码:

     <style>
         html,body{
             width: 100%;
             height: 100%;
         }
         .box1{
             width: 100px;
             height: 100px;
             background-color: red;
             margin-bottom: 50px;
         }
         .box2{
             width: 100px;
             height: 100px;
             background-color: blue;
             margin-top: 50px;
         }
     </style>
<body>
<div class="box1">box1</div>
<div class="box2">box2</div>
</body>
效果显示:

两个盒子之间的距离设置上下各50px,按我们理解的来算应该是100px,但实际上是50px,外边距发生了重叠。
根据BFC规则:

Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠

我们可以把这两个盒子设为不同的BFC,就能避免重叠。实际是给下面的盒子box2设置属性:

.box2{
             width: 100px;
             height: 100px;
             background-color: blue;
             margin-top: 50px;
             display: inline-block;
             /*overflow: hidden;*//在此处无效
         }

效果为:


BFC的这些作用,都体现了BFC的最大的规则属性:

BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。

因为BFC内部的元素和外部的元素绝对不会互相影响,因此, 当BFC外部存在浮动时,它不应该影响BFC内部Box的布局,BFC会通过变窄,而不与浮动有重叠。同样的,当BFC内部有浮动时,为了不影响外部元素的布局,BFC计算高度时会包括浮动的高度。避免margin重叠,也是这样的一个道理。

参考文章:

相关文章

网友评论

      本文标题:外边距重叠

      本文链接:https://www.haomeiwen.com/subject/hgadqxtx.html