谈谈外边距合并及BFC

外边距合并 margin collapse

在块级盒子中,上下外边距可能会出现折叠,即合并成值比较大的那个外边距,这种情况叫外边距合并。注意,指的是垂直方向上的margin。

一、出现外边距合并的情况

1、相邻元素之间
2、父元素与其第一个或最后一个子元素之间
  • 父元素的上外边距和第一个子元素的上外边距
  • 父元素的下外边距和最后一个子元素的下外边距
3、空元素自己的上下外边距会合并

举一个例子:

<p style="margin-bottom: 0px;">段落1</p>

<div style="margin-top: 50px; margin-bottom: 5px;"></div>

<p style="margin-top: 0px;">段落2</p>

这时候段落1和段落2的距离是50px.

如果将段落1或2的参数改为其他数值,这时候又会发生相邻元素(即p与div)的外边距合并。

注意:
  • 两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值。
  • 两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值。
  • 两个外边距一正一负时,折叠结果是两者的相加的和。
  • 即使某一外边距为0,以上规则仍然适用。因此就算父元素的外边距是0,第一个或最后一个子元素的外边距仍然会“溢出”到父元素的外面【理解!】

二、避免外边距合并

1、三种情况都适用的方法

  • 静态文档流元素才会合并,因此可以设置为 float / position: absolute,包括:

    • 相邻的两个相邻的盒模型中,如果其中的一个是浮动的,垂直margin不会被折叠
    • 一个浮动的盒模型和它的子元素之间也不会折叠
  • 设置为 display: inline-block

2、针对相邻元素的合并

  • 包裹一个div,设置overflow:hidden

3、针对父元素与子元素的合并

  • 创建BFC
    • 父元素设置 overflow:auto
    • 父元素设置 overflow: hidden
      • 坏处:内容溢出时会被隐藏。
      • 由于在IE比较低版本的浏览器中使用overflow:hidden;是不能达到这样的效果,因此需要加上 zoom:1;
    • 注意,使用overflow的方法只会解决父元素和子元素之间,在子元素之间还是会存在合并。
  • 通过设置子元素或者父元素的宽高\添加内容\padding\border等将它们的margin隔开

4、针对空元素合并

通过设置border\padding\height等

BFC

在外边距合并问题上我们常常会看见BFC。以上提到的方法很多也是创建了BFC。那么问题来了,BFC到底是什么?在这个问题之前,我们需要先了解盒子模型、

Need to know first

1、Formatting Context

Formatting Context是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及各其他元素的关系和相互作用。

最常见的是BFC(Block Formatting Context)和IFC(Inline Formatting Context)(css2.1),在css3中增加了GFC(GridLayout Formatting Context)、FFC(Flex Formatting Context)。

2、普通流(Normal Flow)

在普通流中,元素按照其在 HTML 中的先后位置至上而下布局,在这个过程中,行内元素水平排列,直到当行被占满然后换行,块级元素则会被渲染为完整的一个新行, 除非另外指定,否则所有元素默认都是普通流定位,也可以说,普通流中元素的位置由该元素在 HTML 文档中的位置决定。

一、BFC是什么

BFC:块格式化上下文(Block Formatting Context)

【MDN】是Web页面的可视化CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域

【MDN】浮动定位和清除浮动时只会应用于同一个BFC内的元素。浮动不会影响其它BFC中元素的布局,而清除浮动只能清除同一BFC中在它前面的元素的浮动。外边距折叠(Margin collapsing)也只会发生在属于同一BFC的块级元素之间

其实BFC属于普通文档流,但是BFC是一个独立的容器,好比一个个大箱子,各箱子之间互不影响,箱子里面的东西(内部元素)相互影响,因此也就可以通过创建BFC来解决元素的外边距合并问题。

BFC的其他特性:

  • 内部的box会在垂直方向,一个接一个地放置
  • 可以包含浮动元素,因此可用来解决因浮动造成的高度塌陷。在计算BFC的高度时,要考虑BFC所包含的所有元素,包括浮动元素。
  • BFC的区域不会与浮动盒子重叠(解决浮动元素文字环绕问题)
  • BFC中,每一个盒子的左外边缘(margin-left)会触碰到容器的左边缘(border-left)(对于从右到左的格式来说,则触碰到右边缘)

二、常见的创建BFC方法

  • 根元素
  • float: 不为”none” (如:float:left/right)
  • overflow: 不为”visible”(如:overflow:hidden)
  • display: table-cell / table-caption / inline-block / flex / inline-flex
  • position: 不为 “static” 或 “relative(如:position:absolute)

三、作用

1、解决外边距合并

就是我们在上面讲到的方法啦,原理就是使外边距合并的对象属于不同的BFC,这样就不会相互影响了。

2、创建自适应两栏布局

<style>
    body {
        width: 300px;
        position: relative;
    }
 
    .aside {
        width: 100px;
        height: 150px;
        float: left;
        background: pink;
    }
 
    .main {
        height: 200px;
        background: blue;
    }
</style>
<body>
    <div class="floatbox"></div>
    <div class="normalbox"></div>
</body>

根据特性:BFC中,每一个盒子的左外边缘(margin-left)会触碰到容器的左边缘(border-left),normalbox左外边缘会和父元素的左边缘接触,因此会和floatbox在左边重叠。

通过特性:BFC的区域不会与浮动盒子重叠,可以给floatbox创建BFC,使它们分离,实现自适应两列布局。

但是这时候floatbox和normalbox还挨在一起,可以通过设置margin分开。最好是设置在floatbox上,设置在normalbox上的值需要很大才能达到我们想要的效果。

推荐:张鑫旭:CSS深入理解流体特性和BFC特性下多栏自适应布局,大佬写的蛮生动哈哈。

3、清除内部浮动,解决父元素高度塌陷

当子元素浮动,父元素没有其它内容时,父元素会出现高度坍塌。
这时候给父元素建立BFC(eg.overflow: hidden;),由于特性: BFC会包含浮动元素,从而让父元素包裹住浮动元素,解决了高度塌陷的问题。

IE7及以下版本不支持BFC,但是它有自己私有的属性hasLayout,可以达到相同的效果,这个下次再整理笔记。(为什么IE总是搞特殊!!!)

经过最近的学习先整理到这,以后有更深的理解了再来更新。
有些用语和细节可能不够准确,欢迎指正~

发布了12 篇原创文章 · 获赞 3 · 访问量 273

猜你喜欢

转载自blog.csdn.net/CcA_Lin/article/details/103329668