ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【Web前端HTML5&CSS3】08- 高度塌陷与BFC

2022-05-20 19:31:59  阅读:209  来源: 互联网

标签:CSS3 Web 元素 HTML5 table BFC 浮动 display 属性


高度塌陷与 BFC

BFC:             全称:Block Formatting Content;是一个与上下文无关的独立的渲染区域;(块级格式化上下文)             是一种布局规则:
  •  内部的Box会在垂直方向,一个接一个地放置。
  •  Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠(按照最大margin值设置)
  •  每个元素的margin box的左边, 与包含块border box的左边相接触
  •  BFC的区域不会与float box重叠。
  •  BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。
  •  计算BFC的高度时,浮动元素也参与计算
                        开启BFC的条件:
  •    默认情况下:html标签(根元素)就是一个大的bfc;
  •    float属性不为none;      (left  right)
  •    overflow不为visible;    (auto  scroll  hidden )
  •    display为inline-block, table-cell, table-caption, flex, inline-flex
  •    position为absolute或fixed;
                注: 在合适的情况下,使用合适的属性开启bfc;

1. 高度塌陷

在浮动布局中,父元素的高度默认是被子元素撑开的

当子元素浮动后,其会完全脱离文档流,子元素从文档流中脱离将会无法撑起父元素的高度,导致父元素的高度丢失

父元素高度丢失以后,其下的元素会自动上移,导致页面的布局混乱

动画2021-41

2. BFC

BFC(Block Formatting Context)块级格式化环境

  • BFC 是一个 CSS 中的一个隐含的属性,可以为一个元素开启 BFC
  • 开启 BFC 该元素会变成一个独立的布局区域

元素开启 BFC 后的特点:

  • 不会被浮动元素覆盖
  • 父子元素外边距不会重叠
  • 可以包含浮动的元素

可以通过一些特殊方式来开启元素的 BFC:

  • 设置为浮动(不推荐):很明显下方元素被覆盖了,总不能让所有元素都浮动吧

    动画2021-40

  • 设置为行内块元素(不推荐):不再独占一行,宽度变了,同时与下方元素产生了一点空隙

    动画2021-39

  • 设置overflow为非visible:既没有覆盖元素,也保持了独占一方的特性(保持了宽度),与下方元素也保持了最初的间隙

    常用的方式为元素设置overflow:hiddenoverflow:auto也是 ok 的) 开启其 BFC, 以使其可以包含浮动元素

    overflow:scroll 会有滚动条,可能并不需要的,所以不太推荐

    动画2021-38

    不过,这种方式也存在一定问题,如下,overflow并没有完全清除 div2 布局上受到的影响

    动画2021-34

总结

  • 可以通过变成浮动元素,来防止自身被浮动元素覆盖(有点“以毒攻毒”那味了)
  • 可以设置行内块,来防止自身及其他元素被浮动元素覆盖(如果说浮动是“独善其身”,那行内块就有点“兼济天下”的意思)
  • 可以设置overflow属性,包含浮动元素(既“独善其身”,又“兼济天下”,但仍有缺陷)

我这里大概翻译了一下,并整理了一份表格,应该看起来更直观一点(有些概念因为还没有学习,翻译和理解有误的地方还望谅解)

元素或属性 说明
<html> 文档根元素
float: left
float: right
浮动元素(float不为none
position: absolut
position: fixed
绝对定位元素
display: inline-block 行内块元素
display: table-cell 表格单元,默认值
display: table-caption 表格标题,默认值
display: table
display: table-row
display: table-row-group
display: table-header-group
display: table-footer-group
display: inline-table
匿名的表格单元,分别是 HTML 表格、表行、表体、表头和表脚的默认值
overflow: hidden
overflow: scroll
overflow: auto
overflow不为visibleclip的块元素
display: flow-root  
contain: layout
contain: content
contain: paint
 
display: flex
display: inline-flex的直接子元素
Flex 项,如果它们本身既不是flex,也不是gridtable容器
display: grid
display: inline-grid的直接子元素
Grid 项,如果它们本身既不是flex,也不是gridtable容器
column-count不为auto
column-width不为auto
Multicol 容器,包含column-count: 1
column-span: all 应该总是创建一个新的格式化上下文,即使column-span: all元素不在 multicol 容器中

 

3. clear

我们这里设计三个兄弟元素,对前两个元素进行float的浮动属性设置,看下效果

动画2021-36

由于 box1 的浮动,导致 box3 位置上移也就是 box3 受到了 box1 浮动的影响,位置发生了改变(注意,这里文字并没有被覆盖,《09-浮动》一节说过浮动的特点,其中第 7 点就是“文字环绕”的问题)

img

如果我们不希望某个元素因为其他元素浮动的影响而改变位置,可以通过clear属性来清除浮动元素对当前元素所产生的影响

clear作用:清除浮动元素对当前元素所产生的影响(本质是为元素添加一个margin-top属性,值由浏览器自动计算)

可选值:

  • left 清除左侧浮动元素对当前元素的影响
  • right 清除右侧浮动元素对当前元素的影响
  • both 清除两侧中影响较大一侧元素的影响(注意,这里不是同时清除两侧的影响)

动画2021-37

4. after

我们学习了上面知识后,了解了高度塌陷问题的解决方式,其中主要有

  • 通过overflow: hidden等可以为元素开启 BFC

    动画2021-35

  • 通过clear: both等可以清除浮动对元素产生的影响

    动画2021-33

同时也了解到,这两种方式都有一定的弊端和隐患。那有没有一种更好的方式去解决高度塌陷的问题呢?

答案当然是:有!

image-20210526233234635

我们直接上效果图

动画2021-32

Q1:这里使用了一个伪元素选择器::after,那有人会问了,跟在 box2 下直接定义一个 box3 有什么区别呢?

A:我们知道,网页的结构思想是:结构+表现+行为。在 box2 下直接定义一个 box3,属于结构;而使用伪元素选择器,属于表现

而高度塌陷问题属于表现问题,定义 box3 的目的是为了撑起 box1 的内容,属于表现,而不是结构,所以在 css 中定义::after更符合网页的编程思想

Q2:为什么需要使用display: block呢?

A:因为默认情况下,::after伪元素是一个行内元素,如果不转为块元素,将仍然撑不起 box1 的高度

image-20210526235431125

5. clearfix

我们在前面《06-盒模型》一节中说过垂直布局中边距重叠的问题:相邻的垂直方向外边距会发生重叠现象

动画2021-30

如上图所示,子元素设置了一个margin-top之后,父元素跟随子元素一起进行了移动

即我们之前说的父子元素间相邻外边距,子元素会传递给父元素(上外边距)

聪明的小伙伴已经想到了,用刚才说的伪元素选择器啊

img

好,我们先来看下效果

动画2021-29

貌似是没有任何变化,到底是什么地方不对呢?

img

我们再来回顾下使用after伪元素的心路历程:

  • 使用无内容的 box3 撑起 box1 ==》表现代替结构(::after代替 box3)
  • clear清除浮动对元素产生的影响(还记得clear的原理么?)

img

其实就是给元素设置了一个margin-top属性,不过这个在开发者工具中是看不到的

既然如此,就相当于在 box2 下面添加一个 box3,然后给 box3 设置一个margin-top属性

到此为止,

∵ 相邻的垂直方向外边距 这个条件仍然满足

∴ 会发生重叠现象这个结论也依然成立

具体点就是,父子元素间相邻外边距,子元素会传递给父元素(上外边距),表现为 box1 和 box2 同步往下移动

那我们应该怎么做才能解决这个问题? 凭你们朴素的情感,应该怎么判? 当然就是让上述条件不满足呗!

怎么能够不满足?当然是让两个元素垂直外边距不相邻啊!

好,多说无益,我们直接上代码看效果!

动画2021-28

我们用了before伪元素选择器,目的当然是让 box1 和 box2 的外边距不相邻,但是好像并没有效果

我们再换成display: inline-block属性看看

动画2021-27

好像是解决了父元素布局的问题,但是子元素怎么还往下跑了一段距离? 是谁给的勇气?

因为inline-block兼顾行内元素和块元素的特点,既可以设置宽高也不独占一行

在没有设置宽高时,会存在一个默认高度,所以inline-block仍然行不通

还有一个属性,display: table

动画2021-26

Bingo!实现了我们最终想要的效果

Q1:为什么没有使用 clear 属性?

A:不是说了吗?clear是为了清除浮动对布局的影响,我们现在没有浮动的元素啊,我们要讨论的也不是浮动的问题

Q2:display 不是还有一个none属性么,为什么不用呢?

A:none属性是不占据位置,但是也不能让元素相邻的外边距分离啊

Q3:为什么table值就可以呢?

A:这个问题问的非常好,算是问到点上了!我们上面在讲开启 BFC 的一些方法的时候,也提到了该属性。而且,应该牢记的是,元素开启 BFC 后的其中一个特点就是 父子元素外边距不会重叠。当然,这里也需要合理选择伪元素选择器,使其外边距不相邻才行

另外,总结一下:

  • 高度塌陷问题,一般用::after
  • 外边距重叠问题,一般用::before

不知道到这里,大家能不能想明白这两件事情

img

那么问题来了,有没有一个两全其美的办法,既可以解决高度塌陷,又可以解决外边距重叠呢?

img

当然有!clearfix 这个样式就可以同时解决高度塌陷和外边距重叠的问题

当你在遇到这些问题时,直接使用clearfix这个类即可,他就可以帮你轻松搞定 css 中的两大难题

CSS
.clearfix::before,
.clearfix::after {
  content: "";
  display: table;
  clear: both;
}

其中.clearfix::before是为了解决外边距重叠问题

CSS
.clearfix::before {
  content: "";
  display: table;
}

.clearfix::after是为了解决高度塌陷问题

CSS
.clearfix::after {
  content: "";
  display: table;
  clear: both;
}

两者合在一起,就可以完美地解决高度塌陷和外边距重叠这两大“世纪难题”了

image-20210528030932616

标签:CSS3,Web,元素,HTML5,table,BFC,浮动,display,属性
来源: https://www.cnblogs.com/https-blog-paofu-net/p/16293516.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有