前端知识体系构建_CSS3(BFC)

172 阅读5分钟

「这是我参与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