前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CSS 基础系列:从清除浮动和margin塌陷问题谈BFC

CSS 基础系列:从清除浮动和margin塌陷问题谈BFC

作者头像
Chor
发布2019-11-07 18:42:17
2.2K0
发布2019-11-07 18:42:17
举报
文章被收录于专栏:前端之旅前端之旅前端之旅

1.清除浮动

浮动的元素会影响其兄弟元素的位置,并可能导致父元素的高度塌陷(假如父元素没设置高度),因此需要清除浮动(带来的影响)。

1.1 方法

常用方法有:

  • 给浮动元素的父元素一个固定高度(不推荐)
  • 给浮动元素新增一个空的 div 兄弟元素,设置 clear:both
  • 给浮动元素新增一个 <br> 兄弟元素,设置 clear 属性为 all
  • 给浮动元素的父元素新增一个 after 伪类,设置该伪类和父元素:
div{
    zoom:1;
}
div:after{
    content:"";
    display:block;
    clear:both;
}    
  • 给浮动元素的父元素设置 display: table(触发BFC)
  • 给浮动元素的父元素也设置浮动(触发 BFC。不推荐)
  • 给浮动元素的父元素设置 overflow: hidden(触发 BFC)

1.2 原理

这里主要说下 clear:bothclear:both 意思是说,设置了该属性的元素,其左边和右边不允许存在浮动元素。

  • 父元素高度塌陷的情况:子元素浮动后脱离了文档流,未设置高度的父元素在形式上表现为 0 高度,设置了 clear:both 的元素为了满足其左右两边没有浮动元素的这个条件,只能自身下移,从而带动了父元素高度的撑开。
  • 兄弟元素覆盖的情况:同理,比如A由于浮动覆盖了 C,我们在 AC 之间新增一个 B 元素,则 BC 位于同一文档流,B 为了满足其左右两边没有浮动元素的这个条件,只能自身下移,从而带动了 C 元素向下移动直到没有被 A 覆盖。

那么为什么除了 clear:both 之外,其他方法也能清除浮动呢?因为那些方法大都触发了 BFC,而 BFC 是可以清除浮动的,这个后面再介绍。

2.margin 塌陷

文档流内,块级元素与块级元素在垂直方向上的 margin 有时会合并(塌陷)为单个 margin,这样的现象称之为 margin 塌陷(margin collapse)。具体包括三种情况:

  • 相邻的兄弟元素之间: 原因: 相邻的兄弟元素默认位于同一个块级上下文中 计算规则: 正正取大值,正负值相加,负负最小值
  • 父元素与第一个/最后一个子元素之间: 原因: a.margin-top 重叠 父元素非块状格式化上下文元素 父元素没有border-top设置 父元素没有padding-top值 父元素和第一个子元素之间没有inline元素分隔 b.margin-bottom 重叠 父元素非块状格式化上下文设置 父元素没有 border-bottom 设置 父元素没有 padding-bottom 值 父元素和第一个子元素之间没有inline元素分隔 父元素没有 height,min-height,max-height 计算规则: 子元素和父元素上边界重叠,并且以子元素的 margin-top 作为父元素的 margin-top 整体移动。对于 margin-bottom 同理。
  • 空的block元素: 原因: 元素没有 border 设置 元素没有 padding 值 里面没有 inline 元素 没有 height 或者min-height

那么怎么解决 margin 塌陷问题呢?同样是利用接下来要讲到的 BFC。

3.BFC

3.1 什么是 BFC?

BFC 即 Block formatting context,译为块级格式化上下文。简单来说,它是一种属性,这种属性影响着元素的定位以及与其兄弟元素之间的相互作用。因为是属性,所以我们通常说“元素具有 BFC”、“元素触发了 BFC”,而不说“元素是 BFC”。

从样式上看,具有 BFC 的元素与普通的容器没有什么区别;但是从功能上,具有 BFC 的元素可以看作是隔离了的独立容器,容器里面的子元素不会在布局上影响到外面的元素,并且 BFC 具有普通容器没有的一些特性。

3.2 如何触发 BFC?

CSS 规定满足下列 CSS 声明之一的元素便会生成 BFC:

  • 根元素或其它包含它的元素;
  • float 的值不为 none;
  • overflow 的值不为 visible;
  • position 的值为 absolute 或 fixed;
  • display 的值为 inline-block、table-cell、table-caption、table、flex、inline-flex、flow-roottable 本身不生成 BFC,而是 table 默认生成的匿名 table-cell 会生成 BFC

3.3 BFC 的特性

从整体上看,BFC 是隔离了的容器,这个具体可以表现为三个特性:

3.3.1 BFC 会阻止 margin 塌陷

前面我们说过 BFC 可以用于解决 margin 塌陷问题。

  • 因为相邻兄弟元素默认位于同一个 BFC 是导致 margin 塌陷的原因,所以我们只需要设法隔离它们两者即可 ———— 假设有兄弟元素 A 和 B,可以使 A 的父元素触发 BFC,此时,触发了 BFC 的父元素里面的 A 子元素不会在布局上影响到 B,也自然不会有 margin 的叠加。
  • 同样地,如果是父子嵌套的 margin 塌陷问题,只需要触发父元素的 BFC 即可。
3.3.2 BFC 可以包含浮动的元素

前面说过,父元素没有设置高度时,子元素的浮动会导致父元素表现为 0 高度,也就是说正常情况下父元素无法包含浮动的子元素。如图:

.Fa{
    border: 2px solid red;
    width: 300px;
}
.son{
    width:180px;
    height:180px;
    background-color:yellow;
    float:left;
}

但是触发了父元素的 BFC 后,父元素将可以包含浮动的子元素。如图:

.Fa{
    border: 2px solid red;
    width: 300px;
    overflow:hidden;  /* 随便一个 BFC 的触发条件 */
}
.son{
    width:180px;
    height:180px;
    background-color:yellow;
    float:left;
}
3.3.3 BFC 可以阻止元素被浮动元素覆盖

前面说过浮动元素会影响兄弟元素的位置,具体地说就是浮动之后脱离了文档流,使得兄弟元素上移填补空缺,而这会使得它被浮动元素覆盖。如图:

但是触发了兄弟元素的 BFC 后,兄元素将不会被浮动的元素覆盖 ———— 不会被覆盖,意味着兄弟元素出现在浮动元素的旁边或者下面,具体取决于父元素的宽度。 如果父元素的宽度足以包含这两个子元素的宽度之和,则子兄弟元素和子浮动元素并排。如图:

如果父元素的宽度不足以包含这两个子元素的宽度之和,则子兄弟元素会出现在子浮动元素的下面。如图:

4.可视化格式模型

让我们进一步拓展一下可视化格式模型的一些概念,由于比较复杂,所以只做了解即可。

可视化格式模型规定了客户端(浏览器)如何在媒介(显示器)中渲染文档树(document tree)。如下图,每个节点、元素都有属于自己的可见或不可见、有名或匿名的盒模型,可视化格式模型即规定了这些盒、框框如何整齐地排列在页面中,还有盒子之间的相互作用。

可视化格式模型的体系包括: 1.包含块 CB(Containing block) 2.控制框:块框、行框 3.FC(Formatting Context, 格式化上下文)

  • BFC(Block Formatting Context, 块级格式化上下文)
  • IFC(Inline Formatting Context, 行内格式上下文)
  • GFC(Grid Formatting Context, 网格布局格式化上下文)
  • FFC(Flex formatting contexts, 自适应格式上下文) 4.定位体系/方案(普通流、定位流、浮动流) 5.浮动体系

这里只说 FC 和定位体系。

4.1 FC

FC 即 Formatting context,译为格式化上下文。这是 W3C CSS2.1 规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系、相互作用。除了最常见的 CSS2.1 中的 BFC 和 IFC 之外,CSS3 中还增加了 GFC 和 FFC。

4.1.1 BFC:

前面已经说过了。

4.1.2 IFC:
  • IFC 的 line box 高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的 padding/margin 影响)。IFC 的line box 一般左右都贴紧整个 IFC,但是会因为 float 元素而扰乱。float 元素会位于 IFC 与 line box 之间,使得 line box 宽度缩短。 同个 IFC 下的多个 line box 高度会不同。
  • IFC 中是不可能有块级元素的,当插入块级元素时(如 p 中插入 div)会产生两个匿名块与 div 分隔开,即产生两个 IFC,每个 IFC 对外表现为块级元素,与 div 垂直排列。
  • 那么IFC一般有什么用呢? 水平居中:当一个块要在环境中水平居中时,设置其为 inline-block 则会在外层产生 IFC,通过 text-align 则可以使其水平居中。 垂直居中:创建一个 IFC,用其中一个元素撑开父元素的高度,然后设置其 vertical-align:middle,其他行内元素则可以在此父元素下垂直居中。
4.1.3 GFC:
  • 当为一个元素设置 display:grid 的时候,此元素将会获得一个独立的渲染区域,我们可以通过在网格容器(grid container)上定义网格定义行(grid definition rows)和网格定义列(grid definition columns)属性各在网格项目(grid item)上定义网格行(grid row)和网格列(grid columns)为每一个网格项目(grid item)定义位置和空间。
  • 那么 GFC 有什么用呢,和 table 又有什么区别呢?首先同样是一个二维的表格,但 GridLayout 会有更加丰富的属性来控制行列,控制对齐以及更为精细的渲染语义和控制。
4.1.4 FFC:

display:flex 或者 display:inline-flex 的元素将会生成自适应容器(flex container),可惜这个牛逼的属性只有谷歌和火狐支持,不过在移动端也足够了,至少 safari 和 chrome 还是 OK 的,毕竟这俩在移动端才是王道。 Flex box 由伸缩容器和伸缩项目组成。通过设置元素display:flex 或者 display:inline-flex 可以得到一个伸缩容器。设置为 flex 的容器被渲染为一个块级元素,而设置为 inline-flex 的容器则渲染为一个行内元素。 伸缩容器中的每一个子元素都是一个伸缩项目。伸缩项目可以是任意数量的。伸缩容器外和伸缩项目内的一切元素都不受影响。简单地说,Flex box 定义了伸缩容器内伸缩项目该如何布局。

4.2 定位方案

在定位的时候,浏览器会根据元素的盒类型和上下文对这些元素进行定位,可以说盒就是定位的基本单位。在 CSS2.1 中,有三种定位方案 ———— 普通流、浮动和绝对定位,下面分别对这三种布局简略说明一下:

普通流(Normal flow)

  • 在普通流中,盒一个接着一个排列;
  • 在块级格式化上下文里面,它们竖着排列;
  • 在行内格式化上下文里面,它们横着排列;
  • 通常情况下, position 为 static 或 relative,并且 float 为 none ,因而会触发普通流;
  • position 为 static 时,盒的位置是常规流布局里的位置;
  • position 为 relative 时,盒偏移位置由 top,bottom,left 和 right 定义。即使有偏移,仍然保留原有的位置,其它普通流不能占用这个位置。

浮动 (Floats)

  • 元素脱离普通流,并且影响普通流的布局 ———— 导致普通流环绕在它的周边,除非设置 clear 属性;
  • 盒称为浮动盒(floating boxes);
  • 它位于当前行的开头或末尾;

绝对定位 (Absolute positioning)

  • 元素脱离普通流,并且不影响普通流的布局
  • 它的定位相对于它的包含块,相关CSS属性:top,bottom,left 和 right;
  • 如果元素为 position:absoluteposition:fixed,它是绝对定位元素;
  • 对于 position: absolute,元素将相对最近的一个非 static 定位的父元素进行定位,如果没有则相对于 body;

参考: 学习 BFC (Block Formatting Context) CSS-可视化格式模型

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-05-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.清除浮动
    • 1.1 方法
      • 1.2 原理
      • 2.margin 塌陷
      • 3.BFC
        • 3.1 什么是 BFC?
          • 3.2 如何触发 BFC?
            • 3.3 BFC 的特性
              • 3.3.1 BFC 会阻止 margin 塌陷
              • 3.3.2 BFC 可以包含浮动的元素
              • 3.3.3 BFC 可以阻止元素被浮动元素覆盖
          • 4.可视化格式模型
            • 4.1 FC
              • 4.1.1 BFC:
              • 4.1.2 IFC:
              • 4.1.3 GFC:
              • 4.1.4 FFC:
            • 4.2 定位方案
            相关产品与服务
            容器服务
            腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档