持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第11天,点击查看活动详情
1、防止父元素高度坍塌的 4 种方案
问题重现:
- 父元素的高度,都是由内部未浮动子元素的高度撑起的。
- 如果子元素浮动起来,就不占用普通文档流的位置。父元素高度就会失去支撑,也称为高度坍塌。
不好的解决方法
给父元素设置固定高度
缺点:多数情况下,父元素高度由内容撑起,很难提前固定父元素的高度。
方案1:(经过测试,只能解决 float引起的坍塌问题,不能解决绝对定位的坍塌问题)
为父元素设置 overflow: hidden 属性。
原理:CSS 中 overflow: hidden 属性会强制要求父元素必须包裹住所有内部浮动的元素,以及所有元素的 margin 范围
缺点:如果刚好父元素有些超范围的子元素内容需要显示(比如,个别 position 定位的子菜单项),不想隐藏,就会发生冲突。
方案2:
在父元素内的结尾追加一个空子元素(块级元素),并设置空子元素清除浮动影响(clear: both)。
原理:利用 clear: both 属性和父元素必须包含非浮动的元素两个原理
缺点:无端多出一个无意义的但不见的空元素,影响选择器和查找元素。
方案3:
设置父元素也浮动。
原理:浮动属性也会强制父元素扩大到包含所有浮动的内部元素。
缺点:会产生新的浮动影响。比如,父元素浮动,导致父元素之后平级的页脚div上移,被父元素挡住了。
方案4:(最好做法)
为父元素末尾伪元素设置 clear: both
在元素开头的结尾各有一个伪元素:::before 和 ::after 。
优点:既不会影响显示隐藏,又不会影响查找元素,又不会产生新的浮动问题。
.parent::after{ content: ""; display: block; clear: both; height: 0; } // 有些游览器display有默认高度
2、BFC
- 什么是BFC(Block formatting context)
- 直译为 “块级格式化上下文”
- 它是网页中一个 独立的渲染区域(也称为 formatting context)
- 这个渲染区域只有块级(Block)元素才能参与。
- 它规定了内部的块级元素如何布局
- BFC渲染区域内部如何布局,与区域外部毫不相干
- 外部元素也不会影响BFC渲染区域内的元素
简单来说:BFC就是页面上的一个隔离的独立渲染区域。
区域里面的子元素不会影响到外面的元素。
外面的元素也不会影响到区域里面的子元素。
css两种渲染区域:块级元素渲染区域和行级元素渲染区域。
- BFC(Block formatting context)
- 块级渲染区域:所有 display 属性为
block, list-item,table的元素,会生成块级元素渲染区域。 - 块级元素渲染区域内以 BFC 方式渲染。
- 块级渲染区域:所有 display 属性为
- IFC(inline formatting context)
- 行级元素渲染区域:display属性为
inline,inline-block,inline-table的元素,会生成行级元素渲染区域。 - 行级元素渲染区域以 IFC 方式渲染
- 行级元素渲染区域:display属性为
BFC的布局规则
- 属于同一个BFC的两个相邻块元素在垂直方向上的 margin 会发生重叠/合并。但水平方向的 margin 不会
- 左侧 BFC 渲染区域的 margin,必须与右侧 BFC 渲染区域的 margin 相衔接,不能出现重叠。
4种情况下会形成BFC渲染区域
- float 的值不是 none
- position 的值不是 static 或者 relative
- display 的值是 inline-block、table-cell、flex、table-caption 或者 inline-flex
- overflow 的值不是 visible
BFC解决问题
问题1:垂直方向上,两个元素上下 margin 相遇时,两元素间的总间距并不等于两个 margin 的和。而是等于最大的 margin。(小的会被大的吞并)
解决:
- 用一个外围块元素包裹下方元素
- 父元素设置样式
::before{ content: ""; display: table; height: 0; }
原理:新的外层元素,变成一个BFC方式的渲染区域,就必须包裹内部子元素及子元素的 margin。而且,内部元素不能超出范围影响外部,外部元素也不能进入 BFC 范围内,影响内部
**问题2:**垂直方向的margin溢出。子元素设置 margin-top,会超出父元素上边的范围,变成父元素的 margin-top,而实际上,子元素与父元素之间,依然是没有margin-top的。
解决方法:5种
- 设置父元素 overflow: hidden
- bfc的方式
- 为父元素添加上边框,颜色设置为透明(transparent)
- 原理:这里不是bfc。而是因为边框本身可以阻隔 margin 溢出
- 缺点:会增大父元素的实际大小,导致布局错乱
- 用父元素的 padding-top 代替第一个子元素的 margin-top
- 在父元素内第一个子元素之前添加一个空的
<table></table>- 原理:table的display属性默认相当于 table,所以形成小的 bfc 渲染区域。
- 优点:空 table 元素没有大小,不占用父元素空间
- 缺点:增加了一个看不见的空元素,干扰查找元素
- 伪类:
父元素::before{ content: ""; display: table; }
问题3:左侧定宽,右侧自适应
第一步:左侧定宽元素左浮动:.left{ float: left; width: 200px }
第二步:右侧元素不用右浮动,而是 .right{ overflow: hidden; }
原理:右边元素 overflow: hidden 后,形成 BFC 渲染区域。左边的 float 元素就不能进入右边范围了。