浮动
为什么要清除浮动?
如果一个父块级元素没有设置height 或者设置 height: auto; 但是里面的所有子元素都设置float: left/right属性
子元素就会脱离标准文档流 不在占据自己原来的位置空间,
这些浮动子元素( 不能像之前没有设置float浮动一样,可以决定撑开父元素高度)不能撑开块级父元素空间高度,导致父元素布局无法正常显示,
这就是子元素浮动导致父容器高度塌陷的问题 ,这也是我们为什么要清除浮动的原因
如果父元素设置了具体的高度值 那么即使 子元素添加了浮动float熟悉 父元素布局也会正常显示 不会出现父元素高度塌陷的问题
一个父元素(高度auto) 2个子元素能撑开父元素案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.top {
background-color: pink;
width: 1100px;
/* height: 100px; */
height: auto;
margin: 0 auto;
}
.left {
width: 200px;
height: 300px;
background-color: #ccc;
margin-left:10px;
}
.right {
width: 790px;
height: 300px;
background-color: skyblue;
margin-left:10px;
margin-right:10px;
}
/* 块级元素宽度默认填充满父容器宽度 */
.bottom {
height: 100px;
background-color: green;
}
</style>
</head>
<body>
<!-- 块级父元素设置height: auto; 高度自适应 高度会自动调整大小以适应其内部所有子元素的高度总和 -->
<div class="top">父
<div class="left">子1</div>
<div class="right">子2</div>
</div>
<div class="bottom">other</div>
</body>
</html>
2个浮动子元素不能撑开父元素高度,导致父元素布局无法正常显示案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.top {
background-color: pink;
width: 1100px;
/* height: 300px; */
height: auto;
margin: 0 auto;
}
.left {
float: left;
width: 200px;
height: 300px;
background-color: #ccc;
margin-left:10px;
}
.right {
float: right;
width: 790px;
height: 300px;
background-color: skyblue;
margin-right:10px;
}
/* 块级元素宽度默认填充满父容器宽度 */
.bottom {
height: 100px;
background-color: green;
}
</style>
</head>
<body>
<!-- 父子级标签, 子级浮动, 父级没有高度, 后面的其他块级标准流盒子会受影响, 显示到上面的位置 完全把这个父给盖掉-->
<div class="top">父
<div class="left">子1</div>
<div class="right">子2</div>
</div>
<div class="bottom">other</div>
</body>
</html>
清除浮动的方法
① 直接给父元素设置具体高度
如果父元素设置了具体的高度值 那么即使 子元素添加了浮动float熟悉 父元素布局也会正常显示 不会出现父元素高度塌陷的问题
- 优点:简单粗暴,方便
- 缺点:有些布局中不能固定父元素高度。如:新闻列表、京东推荐模块
② 添加额外标签(div)法清除浮动
这个清除浮动的 额外标签
<div>
应该放在所有浮动元素之后、父容器结束标签之前。这是最标准且推荐的做法。给这个添加的额外标签
<div>
块级元素设置 clear:both注意:
这个添加的额外标签
<div>必须按照上面的提示放在指定的位置。
如果你把它放在其他位置(比如浮动元素前面或中间),它将无法正常清除浮动,甚至不起作用。为什么这个添加的额外标签必须放在“浮动元素之后”?
clear: both;
的意思是:“不允许我这个额外标签元素左边或右边有浮动元素。”- 所以,只有当这个额外标签元素出现在所有浮动元素后面时,它才能起到“把浮动元素拉下来”的效果。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.top {
background-color: pink;
width: 1100px;
/* height: 300px; */
margin: 0 auto;
}
.left {
float: left;
width: 200px;
height: 300px;
background-color: #ccc;
margin-left:10px;
}
.right {
float: right;
width: 790px;
height: 300px;
background-color: skyblue;
margin-right:10px;
}
/* 块级元素宽度默认填充满父容器宽度 */
.bottom {
height: 100px;
background-color: green;
}
.clearfix {
/* 清除左右两侧浮动的影响 */
clear: both;
}
</style>
</head>
<body>
<!-- 父子级标签, 子级浮动, 父级没有高度, 后面的其他块级标准流盒子会受影响, 显示到上面的位置 完全把这个父给盖掉-->
<div class="top">父
<div class="left">子1</div>
<div class="right">子2</div>
<div class="clearfix"></div>
</div>
<div class="bottom">other</div>
</body>
</html>
③ 使用单伪元素::after清除浮动
/* 清除浮动,避免影响后续布局 */
.clearfix::after {
content: ""; // 伪元素必加的属性
display: block; // 伪元素默认是行内元素,需要转换成块级元素
clear: both; //清除浮动的核心代码
/*补充的代码(作用:就是在页面中看不到伪元素) 为了兼容性 */
height: 0;
visibility: hidden;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.top {
background-color: pink;
width: 1100px;
/* height: 300px; */
margin: 0 auto;
}
.left {
float: left;
width: 200px;
height: 300px;
background-color: #ccc;
margin-left:10px;
}
.right {
float: right;
width: 790px;
height: 300px;
background-color: skyblue;
margin-right:10px;
}
/* 块级元素宽度默认填充满父容器宽度 */
.bottom {
height: 100px;
background-color: green;
}
/* 使用伪元素::after清除浮动 与 添加额外标签(div)法清除浮动 原理是一样的 */
.clearfix::after{
content: '';
/* 伪元素添加的标签是行内, 要求块 */
display: block;
/* 清除左右两侧浮动的影响 */
clear: both;
/*补充的代码(作用:就是在页面中看不到伪元素) 为了兼容性 */
height: 0;
visibility: hidden;
}
</style>
</head>
<body>
<!-- 父子级标签, 子级浮动, 父级没有高度, 后面的其他块级标准流盒子会受影响, 显示到上面的位置 完全把这个父给盖掉-->
<div class="top clearfix">父
<div class="left">子1</div>
<div class="right">子2</div>
<div class="clearfix"></div>
</div>
<div class="bottom">other</div>
</body>
</html>
④ 使用双伪元素(::before 和 ::after)清除浮动
使用双伪元素(::before 和 ::after)
- ::after清除浮动 解决父元素高度塌陷问题
- ::before解决父元素外边距塌陷现象
使用双伪元素(::before 和 ::after)做法更全面:清除浮动解决父元素高度塌陷 解决父元素外边距塌陷问题
方法 清除浮动
(解决父元素高度塌陷)
解决父元素外边距塌陷 是否推荐 单伪元素 ::after ✅ 是 ❌ 否 ⚠️ 推荐一般场景 单用 overflow: hidden ✅ 是 ✅ 是 ✅ 推荐 双伪元素使用 ::before + ::after ✅ 是 ✅ 是 ✅✅ 强烈推荐(更严谨) 注意:
❶浮动子元素设置 margin-top 不会影响父元素的位置,也不会导致父元素外边距出现塌陷问题。
- 浮动子元素脱离文档流,不在处于自己原来的位置空间,所以浮动子元素与父元素没有任何瓜葛了,也不会让父元素出现外边距塌陷的问题。
- 但是会引出另一个问题就是 浮动子元素的高度不会决定父元素的高度 ,导致父元素高度(没有高度值0)塌陷问题
❷只有非浮动子元素设置 margin-top 才会导致父元素出现外边距塌陷问题
外边距塌陷问题:
非浮动子元素设置了 margin-top往下偏移,会“穿透”到父元素外面,导致父元素也跟着向下偏移;
.top 是一个父块级元素,没有设置 height,里面的子元素设置float属性,脱离自己的标准
子元素就会脱离标准文档流 不在占据自己原来的位置空间,这些浮动子元素 不能撑开块级父元素空间高度,导致父元素布局无法正常显示, 导致父容器高度塌陷
.clearfix::after { content: ''; display: table; clear: both; }
在 .top 元素的内容后面插入一个虚拟元素;
设置 clear: both; 表示:“不允许我这个位置左边或右边有任何浮动元素”;由于这个虚拟元素位于所有浮动元素之后,所以它会强制把整个浮动区域“拉下来”,从而撑开父容器 .top 的高度;.clearfix::before {
content: '';
display: table;
}
使用 ::before 解决外边距塌陷
插入一个虚拟元素在 .top 内容开始前;
设置为 display: table; 会创建一个新的 BFC(块级格式化上下文);
这样可以防止 .left 或 .right 中的 margin-top 影响到 .top 的位置;
⑤ 给父元素设置overflow : hidden/auto属性
通过设置父元素的 overflow : hidden / auto 来创建一个新的块级格式化上下文(BFC),这样父元素就会包含其浮动子元素。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.top {
background-color: pink;
width: 1100px;
/* height: 300px; */
margin: 0 auto;
overflow: hidden; /* 或 auto */
}
.left {
float: left;
width: 200px;
height: 300px;
background-color: #ccc;
margin-left:10px;
}
.right {
float: right;
width: 790px;
height: 300px;
background-color: skyblue;
margin-right:10px;
}
/* 块级元素宽度默认填充满父容器宽度 */
.bottom {
height: 100px;
background-color: green;
}
</style>
</head>
<body>
<!-- 父子级标签, 子级浮动, 父级没有高度, 后面的其他块级标准流盒子会受影响, 显示到上面的位置 完全把这个父给盖掉-->
<div class="top">父
<div class="left">子1</div>
<div class="right">子2</div>
</div>
<div class="bottom">other</div>
</body>
</html>