Loading

浮动引发的高度塌陷问题及其解决方法(BFC相关概念及性质)

浮动引发的高度塌陷问题

高度塌陷问题的产生

当原本处于父容器中的元素脱离文档流后,父容器发生高度丢失的问题

<style>
	.outer{
		border: 5px red solid;
	} 

	.inner{
		width: 100px;
		height: 100px;
		background-color: orange;

		/* 由于子元素设置浮动脱离文档流,使得在文档流中的父元素高度丢失 */
		float: left;
	}
</style>
<div class="outer">
    <div class="inner"></div>
</div>

BFC(Block Formatting Context)的引入

BFC又称块级格式化上下文环境,开启BFC的元素会变成一个独立的布局区域

元素开启BFC后的特点

开启BFC的元素不会被其他浮动元素所覆盖

<style>
div{
    width: 100px;
    height: 100px;
}

.box1{
    background-color: chartreuse;
    /* 开启浮动脱离文档流后,box2按正常情况应该会在box1原来的位置(被box1覆盖住) */
    float: left;
}

.box2{
    background-color: crimson;
    /* 但是box2开启BFC后就能做到不被box1覆盖 */
    /* 由于box1不会再独占一行(高度与宽度由内容撑开),所以box2会排列在box1右侧 */
    overflow: hidden;
    
}
</style>
<body>
    <div class="box1"></div>
    <div class="box2"></div>
</body>

开启BFC的元素不会发生父子元素外边距重叠

<style>
    .father{
        width: 200px;
        height: 200px;
        background-color: crimson;
        /* 为父元素开启BFC,解决外边距重叠问题 */
        overflow: hidden;
    }

    .son{
        width: 100px;
        height: 100px;
        background-color: #bfa;
        /* 发生外边距重叠 */
        margin-top: 80px;
    }
</style>
<body>
    <div class="father">
        <div class="son"></div>
    </div>
</body>

开启BFC后可以包含浮动的子元素

<style>
	.father{
	    border: 3px red solid;
	    /* 为父元素开启BFC,使得其能够包裹住浮动元素 */
	    overflow: hidden;
	}

	.son{
	    width: 100px;
	    height: 100px;
	    background-color: #bfa;
	    /* 设置浮动触发高度塌陷 */
	    float: left;
	}
</style>
<body>
    <div class="father">
        <div class="son"></div>
    </div>
</body>

如何开启BFC

设置元素浮动

float: left
float: right

将元素display属性设置为inline-block、table等

display: inline-block
display: table

overflow属性设置为非visible值

overflow: hidden;   <!-- 常用方式 -->
overflow: auto;
overflow: scroll;

开启定位

position: absolute;
position: fixed;

高度塌陷解决方法1: 父元素高度写死

<style>
	.outer{
  		border: 5px red solid;
		/* 将父元素高度写死 */
		height: 100px
	} 

	.inner{
		width: 100px;
		height: 100px;
		background-color: orange;

		/* 由于子元素设置浮动脱离文档流,使得在文档流中的父元素高度丢失 */
		float: left;
	}
</style>
<div class="outer">
    <div class="inner"></div>
</div>

缺点: 无法依据子元素的大小进行灵活改变

高度塌陷解决方法2: 为父元素也设置浮动

子元素是因为浮动(开启BFC)导致脱离文档流,所以为父元素同样设置浮动(开启BFC)就能解决

<style>
    .father{
        border: 3px red solid;
        /* 为父元素开启BFC,使得其能够包裹住浮动元素 */
        float: left;
    }

    .son{
        width: 100px;
        height: 100px;
        background-color: #bfa;
        /* 设置浮动触发高度塌陷 */
        float: left;
    }
</style>
<body>
    <div class="father">
        <div class="son"></div>
    </div>
</body>

缺点: 影响其他还在文档流中元素的布局,父元素的宽度由子元素撑开

高度塌陷解决方法3: 使用clear属性清除浮动对元素的影响

<style>
    .father{
        border: 3px red solid;
    }

    .clear{
        /* clear属性的原理: 浏览器自动计算浮动元素对当前元素的影响范围
        然后通过自动计算设置margin来解除影响 */
        clear: both;
    }

    .son{
        width: 100px;
        height: 100px;
        background-color: #bfa;
        /* 设置浮动触发高度塌陷 */
        float: left;
    }
</style>
<body>
    <div class="father">
        <div class="son"></div>
        <!-- 增加一个看不见的子元素,通过clear的原理来摆脱son脱离文档流对father的影响(高度塌陷) -->
        <!-- 原理:  .clear如果没收到浮动影响会处于.son的下面,刚好能撑开父元素 -->
        <div class="clear"></div>
    </div>
</body>

缺点: 增加了html结构

高度塌陷解决方法4(最终推荐): ::after伪元素结合clear属性

使用::after伪元素有效解决了使用clear属性导致html结构增加的缺点
注意: ::after伪元素用于为已选中元素的最后添加虚拟子元素,这个处于最后的虚拟子元素默认是行内元素

<style>
    .father{
        border: 3px red solid;
    }

    .son{
        width: 100px;
        height: 100px;
        background-color: #bfa;
        /* 设置浮动触发高度塌陷 */
        float: left;
    }

    /* 使用伪元素有效解决了使用clear属性导致html结构增加的缺点 */
    .father::after{
        content: '';
        clear: both;
        /* 此时还不够: 因为::after元素是行内元素 */
        display: table; /* 需要转换成为块元素 */
        /* 虽然在这没用,但是需要知道display同时也开始了BFC属性 */
    }
</style>
<body>
    <div class="father">
        <div class="son"></div>
    </div>
</body>

clearfix类封装解决高度塌陷与外边距重叠

/* 解决外边距重叠 */
.clearfix::before{
    /* 由于必须使用margin属性,所以解决思路是破坏两个margin相邻的状态,而不是转向使用padding */
    content: '';
    /* 使用table的好处:
            -   既能将虚拟元素变成块元素
            -   同时在内容为空时,不占据空间(block会占据) 
    */
    display: table;
}

/* 解决高度塌陷 */
.clearfix::after{
    content: '';    /* 在父元素最末添加虚拟子元素 */
    clear: both;    /* 清除这个子元素收到的浮动影响 */
    display: table; /* 既让这个虚拟子元素变成块元素(默认是行内元素),又让其在没有内容的情况下不占据空间 */
}

/* clear: both 只作用于浮动元素影响的元素,而clearfix是放在虚拟元素中的,所以可以放心合并 */
.clearfix::before,
.clearfix::after{
    content: '';    /* 在父元素最末添加虚拟子元素 */
    clear: both;    /* 清除这个子元素受到的浮动影响 */
    display: table; /* 既让这个虚拟子元素变成块元素(默认是行内元素),又让其在没有内容的情况下不占据空间 */
}
posted @ 2021-02-10 23:49  虚伪渲染敷衍  阅读(485)  评论(0编辑  收藏  举报