HTML/CSS+Bootstrap开发中Div元素重叠的原因解析
重叠问题根本原因:浮动元素的文档流特性与Bootstrap栅格实现机制
这个问题是CSS浮动布局最典型的坑,核心诱因和Bootstrap栅格的实现方式直接相关,所有现象都可以用浮动的布局规则解释:
前置知识:浮动的核心布局规则
Bootstrap 4版本的栅格系统,是通过给.col-*类添加float: left实现多列横向并排的,而浮动元素有三个和普通块级元素完全不同的布局特性:
- 浮动元素会脱离普通文档流,普通块级元素无法感知浮动元素的占位,会直接排布到浮动元素的下方位置,视觉上就形成重叠
- 只有行内级内容(文本、图片、按钮等行内/行内块元素)可以识别浮动元素的边界,会主动绕开浮动区域排布,不会被浮动元素覆盖
- 没有触发BFC(块级格式化上下文)、也没有手动指定高度的普通块级父元素,不会计算内部浮动子元素的高度,会出现高度塌陷——父元素高度远小于内部内容高度,甚至变成0
对应你代码中的问题点
你的代码里触发重叠的直接原因是:
你给作为普通块级容器的.header-section错误添加了col-lg-12类,导致整个header容器本身变成了左浮动元素,脱离了普通文档流。后续的.description-section作为普通块级元素,感知不到这个浮动header的占位,直接顶到了页面最顶部排布,因此和header产生重叠。
同时你在header内部放置的两个列.column1、.column2也都是带col-lg-6的浮动元素,如果你没有给header手动设置height: 400px,header还会因为内部子元素全是浮动元素出现高度塌陷,同样会导致后续元素上移重叠。
你观察到的所有现象的对应解释
- 为什么第三个div(
.another-description-section)没有出现重叠?
你给.description-section设置了overflow: auto,这个属性会触发元素的BFC。BFC是页面上的独立渲染区域,有两个关键特性:不会和外部浮动元素重叠、会占据正常文档流位置把后续元素往下挤。因此.description-section虽然一开始上移,但触发BFC后会自动避开浮动的header调整位置,同时把后面的第三个div正常顶到下方,所以第三个div不会重叠。如果去掉.description-section的overflow: auto属性,第三个div一样会出现重叠。 - 为什么在header和第二个div之间插入一个带文本的普通div,重叠就消失了?
插入的div里的文本属于行内内容,会主动绕开前面的浮动header,把插入div的整体高度撑开,相当于在两个区块之间加了一个占位块,自然就把后面的.description-section挤到了正常位置。 - 为什么加
clear: both或者overflow: hidden/auto能解决问题?clear: both的作用是显式声明当前元素左右两侧不允许存在浮动元素,浏览器会自动把当前元素往下移动,直到两侧没有浮动元素为止,从规则上避免了重叠overflow: hidden/auto的核心作用是触发元素的BFC,BFC区域天然不会和外部浮动元素重叠,因此会自动调整位置避开前面的浮动header
- 为什么其他写了类似代码的页面不会出现重叠?
正常使用Bootstrap栅格时,所有.col-*类都必须放在.row容器内部,而Bootstrap自带的.row类默认写了清除浮动的样式(通过::after伪元素实现clear:both),会自动解决内部浮动导致的高度塌陷、元素重叠问题。你现在跳过了.row容器,直接给普通div加.col-*类,甚至把外层容器本身也加了col类变成浮动元素,才触发了浮动的布局异常。
正确修复方案
按照Bootstrap栅格的标准结构编写DOM即可,栅格类不要直接套在普通容器上,标准层级为容器(.container/.container-fluid) > 行(.row) > 列(.col-*):
<link rel="stylesheet" href="本地Bootstrap4样式文件路径"> <div class="container-fluid"> <div class="row"> <!-- row自带清除浮动,自动解决内部col的浮动问题 --> <div class="col-lg-12 header-section"> <div class="row"> <div class="col-lg-6 column1"> <div class="inner-content1"> <div class="logo-style"></div> <div class="logo-description"></div> </div> </div> <div class="col-lg-6 column2"> <div class="inner-content2" style="background-color:antiquewhite;"> <div class="contact-or-whatever-info" style="background-color:brown;"></div> </div> </div> </div> </div> </div> </div> <div class="description-section"> <div class="inner-description">second div</div> </div> <div class="another-description-section"> <div class="inner-description">third div</div> </div>
如果你不想调整DOM结构,也可以直接去掉.header-section上的col-lg-12类,或者给它加一个通用clearfix类:
.clearfix::after { content: ""; display: block; clear: both; }
另外你提到的固定顶部导航栏布局正常,是因为固定定位和浮动的脱离文档流机制不同:固定定位元素是相对于视口偏移,默认会覆盖下层内容,只要给body加对应导航栏高度的padding-top就能解决占位问题,和本次的浮动重叠不是同一个技术点。
内容的提问来源于stack exchange,提问作者Salman Abbas
相关产品推荐
相关产品推荐

