「这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战」。
防止高度坍塌4种方案
为什么会出现高度坍塌?
父元素的高度,都是靠内部未浮动的子元素的高度来撑起来的。
子元素如果浮动,会对父元素造成影响,浮动意味着它脱离了普通文档流,父元素的高度就会失去支撑,也就是会出现高度坍塌。
高度坍塌代码及演示
<body>
<div class="parent">
parent
<div class="child">
child
</div>
</div>
</body>
<style>
.parent {
border: 20px black;
}
.child {
float: right;
background-color: red;
width: 100px;
height: 200px;
}
</style>
比较差的解决方法
给父元素设置固定高度,它就不需要子元素的高度来支撑了
缺点:很多情况下,父元素的高度是靠子元素来撑起,很难知道它的高度
4种解决方案
方案一
父元素设置overflow:hidden属性
原理:css中的overflow:hidden属性会强制要求父元素必须包裹住所有内部浮动的元素,以及所有元素的margin范围
缺点:如果刚好父元素有些超范围的子元素内容需要显示,比如某些postition定位的子菜单项,不想隐藏,就会发现冲突。
方案二
在父元素内的结尾追加一个空的子元素(块级元素),并且这个空的子元素清除浮动影响(clear:both)
原理:利用clear:both属性清除浮动影响和非浮动元素支撑父元素的高度两个原理。
缺点:创造了一个没有一点用的空元素,dom多了一个结点,影响选择器查找元素
方案三
让父元素也浮动
原理:浮动属性也会强制父元素可包含浮动子元素
缺点:会产生浮动的副作用,比如,父元素浮动,导致父元素之后平级的页脚上移,被父元素遮挡,所以这样子平级元素也要使用clear:both来清除浮动影响
完美方案四
为父元素末尾伪元素设置clear:both
优点,不会影响显示隐藏问题,也不会影响查找元素,也不会产生新的浮动问题
方案模板
<style>
.parent::after {
display: block;
content: '';
clear: both;
/* height: 0;overflow: hidden; 为了解决 IE 浏览器的兼容问题 */
height: 0;
overflow: hidden
}
</style>
BFC
为什么overflow和float会强制父元素包裹浮动的子元素。这是由于BFC(Block Formatting Context)
什么是BFC
BFC是页面上的一个隔离的独立渲染区域
区域内的子元素不会影响到外面的元素
外面的元素也不会影响区域内的元素
两种渲染区域
其实css有两种渲染区域(Formatting Context)分为块级和行级
块级(Block)就是刚刚提到的BFC,那么行级(Line)就是LFC.
BFC:所有display属性为block,list-item,table的元素,会产生块级元素渲染区域
块级元素渲染区域内以BFC方式渲染
IFC:所有display属性为inline,inline-block,inline-table的元素,会生成行级元素渲染区域
行级元素渲染区域内以IFC方式渲染
BFC布局规则
默认地,内部的块元素会在垂直方向,一个接一个地防止每个块元素占一行。
属于同一个BFC的两个相邻块元素在垂直方向上的margin会发生重叠/合并,水平方向的并不会
块元素的垂直方向总距离由边框内大小和margin共同决定
计算父元素BFC渲染区域的高度的时候,内部浮动元素的高度都要计算在内
形成BFC渲染区域的4种情况
- float的值不是none
- position的值不是static或者relative
- display的值是inline-block,table-cell,flex,table-caption或者inline-flex
- overflow的值不是visible
BFC可以解决的更多问题
解决高度坍塌
方案一中给父元素设置了overflow:hidden属性
因为overflow的值不是visible,所以形成了BFC区域,父元素必须包含包括浮动元素在内的子元素.
方案三中设置父元素也浮动
因为父元素float的值不是none,所以也形成了BFC区域,父元素必须包含包括浮动元素在内的子元素.
避免垂直方向margin合并
垂直方向上,两个元素上下margin相遇的时候,两元素的总间距并不等于两个margin的和,而是等于最大的那个margin,小的margin会被大的margin给吞并。
<body>
<div class="parent">
parent
<div class="child1">
child
</div>
<div class="child2">
child
</div>
<div class="child3">
child
</div>
</div>
</body>
<style>
* {
padding: 0px;
margin: 0px;
}
.parent {
margin: auto;
background-color: green;
display: inline-blocks;
}
.child1 {
margin: 100px;
background-color: orange;
width: 100px;
height: 200px;
}
.child2 {
margin: 40px;
background-color: orange;
width: 100px;
height: 200px;
}
.child3 {
margin: 10px;
background-color: orange;
width: 100px;
height: 200px;
}
</style>
解决方法:
用一个外围块包裹child
将外围块设置overflow:hidden,形成BFC,因为BFC内部不能影响外部,外部不能影响内部,解决了margin合并问题。
但这样也会带来问题,如果父元素中部分自由定位的子元素,希望即使不在父元素的范围,也要显示,那就冲突了。
解决方法,父元素::before{ content:””; display:table}
原理: display:table,在子元素之前形成平级的bfc渲染区域。不允许 子元素的margin进入::before范围内。
优点: 既不隐藏内容,又不添加新元素,又不影响高度
还有两种用途只罗列答案,不作分析,留给大家思考
避免垂直方向margin溢出
五种解决
父元素overflow:hidden
父元素下第一个子元素前添加空
父元素padding代替子元素margin
父元素+透明上边框
父元素::before{ content:””; display:table }
左定宽,右自适应布局
Step1: 左: float:left
Step2: 右: 右overflow:hidden