浮动
理解浮动
浮动就是将一个元素拉到容器的一侧,让文档流在该浮动元素的周围流动。通过float属性来声明一个元素作为浮动元素,不管元素原来是什么类型的,浮动后得到的都是块级框(以外边距为界限)。
- 浮动元素的容纳块是最近的块级祖辈元素,因此浮动元素会向左或向右移动到容纳块的边界(也即与图中<p>元素的左边界相平齐);
- 浮动元素的顶边不能超过文档源码中出现在浮动元素之前的元素生成的框体所在的行框的顶边(如上图所示:要浮动的图像在段落P2的第二行,那么浮动后图像的顶边不会超过第一行所在框体的底边,应该与第二行平齐);
- 由于浮动元素脱离文档流,因此图中段落2的高度是不会增长到能够容纳该图片,而且下一段文字也会接着段落2的下面在图片周围浮动,可以为段落3的<p>元素清除浮动,使其内容紧贴图片下方放置,而不是在右边流动;
浮动可能会引起的问题
父元素高度塌陷
<!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/html"> <head> <meta charset="UTF-8"> <title>Title</title> <link type="text/css" rel="stylesheet" href="test.css"> </head> <body> <div class="main"> <div class="d"></div> <div class="e"></div> </div> <div class="footer"> <p>Gumbo beet greens corn soko <strong>endive</strong> gumbo gourd. Parsley shallot courgette tatsoi pea sprouts fava bean collard greens dandelion okra wakame tomato. Dandelion cucumber earthnut pea peanut soko zucchini.</p> </div> </body> </html>
.main{ background-color: gray; } .footer{ background-color: skyblue; height: 100px; } .d{ background-color: red; width: 100px; height: 100px; float: left; } .e{ background-color: blue; width: 100px; height: 100px; float: left; }
效果如下:
可以看到,原本灰色背景的.main块级框不见了,而紧跟着它的下一个<div>元素直接上升到它的位置。这是因为类名为.main的<div>元素设置的是自然高度(即没有明确设置height属性,其高度随着内容增长而增长),而它里面的两个子元素都是浮动元素,脱离文档流,造成父元素.main高度为零。而与父元素同级的.footer元素则会上升到父元素位置,补全空缺,也将造成浮动元素遮挡了上升的块级元素(注意:行内元素不会被遮挡住,它会在浮动元素四周流动,如图中的文字段落)。
解决方法:
① 清除浮动
为了不增加额外的<div>标签,我们在包含浮动元素的容器中使用伪元素::after来实现清除浮动。它的作用是在容器末尾添加一个元素(不用在HTML中添加标记),对它使用clear属性来清除浮动,这样这个末尾元素就会排布在浮动元素的下一行,“撑起”容器的高度。
.main::after{ display: block; /*设置为块级元素才会排布在浮动元素的下一行*/ content: ""; /*空字符串,为伪元素设置内容以便它出现在文档,若缺少该设置,伪元素则不会出现在文档,无法撑起容器高度*/ clear: both; /*清除浮动*/ }
效果如下:
② 建立BFC
为包含浮动元素的容器建立一个块级格式化上下文(block formatting context,BFC),创建了BFC的容器内部会包含所有的浮动元素,也能达到上图的效果。
.main{ background-color: gray; overflow: auto; }
非均匀排布
<!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/html"> <head> <meta charset="UTF-8"> <title>Title</title> <link type="text/css" rel="stylesheet" href="test.css"> </head> <body> <div class="main"> <div class="b">1</div> <div class="c">2</div> <div class="d">3</div> <div class="e">4</div> </div> </body> </html>
.main { background-color: gray; width: 600px; height: 600px; margin: auto; overflow: auto; } .b{ background-color: green; width: 200px; height: 200px; float: left; margin: 10px; } .c{ background-color: yellow; width: 200px; height: 150px; float: left; margin: 10px; } .d{ background-color: red; width: 200px; height: 200px; float: left; margin: 10px; } .e{ background-color: blue; width: 150px; height: 150px; margin: 10px; float: left; }
效果如下:
由于容器宽度有限,预想中的情况应该是序号为3和4的<div>元素另起一行向左浮动,但效果并不如我们所愿。因为浏览器会将浮动元素尽可能地靠上排布,因此序号为3的<div>元素会浮动到序号为1的<div>元素的右下角,而由于序号为3的<div>元素右边的宽度不足以容纳序号为4的<div>元素,因此序号为4的<div>元素会另起一行向左浮动。
解决办法:
如果我们是想每行排布两个<div>元素,可以使用:nth-child(odd)伪类选择器选择第奇数个<div>元素,对其清除浮动,这样每个序号为奇数的<div>元素都会另起一行。
div:nth-child(odd){ clear: left; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)