LI内嵌套UL覆盖下方内容不推动下移,排查无absolute定位的布局异常
嵌套树列表布局重叠根因排查
在全程未使用position: absolute脱离文档流的前提下,嵌套UL叠在下方内容上、无法推开相邻内容的布局异常,基本都是由两类非定位属性破坏了普通文档流的高度计算逻辑导致的,逐一核对就能快速定位问题:
第一类:父节点写死固定高度,引发子列表溢出
开发树视图时,为了对齐节点的展开图标、文本行高,很容易给包裹节点文本的外层LI设置和单行文本相等的固定height,完全没有预留嵌套子列表的展示空间:
- 此时这个LI在文档流中占据的总高度,只会等于设置的固定高度值
- 嵌套在LI内部的子UL因为没有被计入父元素的高度计算,在父元素
overflow为默认值visible(溢出内容不裁剪)的情况下,会直接从固定高度的容器中向下溢出 - 由于文档流中这个LI的占位高度已经被写死,它下方相邻的兄弟节点、后续区块不会被溢出的UL向下推开,最终表现为子UL直接叠在下方内容上方
这类场景下的典型错误配置类似:
.tree li { /* 为对齐文本写死的单行高度,没有预留子列表空间 */ height: 24px; line-height: 24px; }
第二类:浮动未清除引发的父容器高度塌陷
如果为了实现图标与文本对齐、树节点横向排布的效果,给一级节点LI设置了左右浮动,且没有给浮动元素的父级容器做浮动清除,就会触发经典的高度塌陷问题:
- 浮动元素会脱离普通文档流,父级UL无法感知到内部浮动LI的实际高度,自身高度会收缩为0
- 本来应该排在树容器下方的相邻内容,会直接顶到树容器的起始位置排版
- 当展开嵌套的子UL时,子UL的内容就会直接叠在已经顶上来的下方内容上面
这类场景下的典型错误配置类似:
.tree > li { float: left; width: 100%; }
快速定位的验证方法
在测试代码里临时给所有元素加上1px的红色实线边框,运行后观察排版:
- 如果看到嵌套UL所在的父LI高度刚好和单行文本齐平,完全没有包裹住内部的子UL,就属于第一类固定高度写死的问题
- 如果看到包裹整个树的最外层UL高度为0,完全没有撑起树的整体范围,就属于第二类浮动塌陷的问题
对应修复方案
- 针对固定高度引发的溢出:把LI上的固定
height替换为上下方向的padding来撑开行高,不要给LI写死固定高度,让它随内部嵌套UL的高度自动适配 - 针对浮动引发的塌陷:给树的最外层UL加上
::after伪元素做浮动清除,或者直接给父元素设置overflow: auto触发BFC,让父元素可以正确计算内部浮动元素的总高度
内容的提问来源于stack exchange,提问作者Programnik
相关产品推荐
相关产品推荐

