传统布局技术
浮动、定位、BFC 与经典布局方案。
1. 浮动布局 (Float)
1.1 浮动基础
浮动最初是为图文环绕设计的,后来被广泛用于布局。元素设置 float 后会脱离文档流,向指定方向靠拢,直到碰到容器边缘或另一个浮动元素。
.float-left {
float: left;
}
.float-right {
float: right;
}
<div class="container">
<div class="float-left" style="width:100px;height:100px;background:#e74c3c;">A</div>
<div class="float-left" style="width:100px;height:100px;background:#3498db;">B</div>
<p>这段文字会环绕在浮动元素旁边……</p>
</div>
效果图描述:两个色块 A(红)、B(蓝)并排靠左,文字在右侧环绕排列。
1.2 浮动的副作用——高度塌陷
当子元素全部浮动时,父容器无法感知子元素高度,导致”高度塌陷”:
.parent {
border: 2px solid #333;
/* 没有设置 height,子元素浮动后父元素高度为 0 */
}
.child {
float: left;
width: 100px;
height: 100px;
}
<div class="parent">
<div class="child" style="background:#e74c3c;">A</div>
<div class="child" style="background:#3498db;">B</div>
</div>
<p>这段文字会紧贴在父容器下方,而非在子元素下方</p>
效果图描述:父容器边框塌缩为一条线(高度为0),两个色块溢出,后续文字紧贴边框线。
1.3 清除浮动(Clearfix)方案汇总
方案一:额外标签法(不推荐)
在浮动元素后添加一个空标签并设置 clear: both:
<div class="parent">
<div class="child">A</div>
<div class="child">B</div>
<div style="clear:both;"></div>
</div>
缺点:增加无语义标签,违反结构与表现分离原则。
方案二:父元素设置 overflow: hidden(BFC 法)
.parent {
overflow: hidden;
}
原理:触发 BFC,BFC 会包含浮动元素。但 overflow: hidden 会裁剪溢出内容,不适合需要溢出显示的场景。
方案三:伪元素清除法(推荐 [完成])
.clearfix::after {
content: '';
display: block;
clear: both;
}
.clearfix {
*zoom: 1;
}
*zoom: 1 是 IE6/7 的 hack,触发 hasLayout 以兼容老浏览器。
方案四:现代 BFC 方案
.parent {
display: flow-root;
}
display: flow-root 专门为创建 BFC 设计,无副作用。浏览器支持:Chrome 58+、Firefox 53+、Safari 13+。
1.4 clear 属性详解
.clear-left {
clear: left;
}
.clear-right {
clear: right;
}
.clear-both {
clear: both;
}
clear: left:元素顶部不允许有左浮动元素clear: right:元素顶部不允许有右浮动元素clear: both:两侧都不允许
2. 定位系统 (Positioning)
CSS position 属性控制元素的定位方式,配合 top/right/bottom/left/z-index 使用。
2.1 static——默认定位
所有元素默认 position: static,遵循正常文档流。top/left 等偏移属性无效。
.box-static {
position: static;
top: 50px;
left: 100px;
}
效果图描述:元素位置无任何变化,
top/left不生效。
2.2 relative——相对定位
相对于自身原位置偏移,不脱离文档流,原位置仍保留空间。
.box-relative {
position: relative;
top: 20px;
left: 30px;
}
<div style="background:#ecf0f1;padding:20px;">
<span>前</span>
<span class="box-relative" style="background:#e74c3c;color:#fff;padding:5px;">相对定位</span>
<span>后</span>
</div>
效果图描述:“相对定位”文字向右下偏移 30px/20px,但原位置仍留有空间,“前""后”文字位置不变。 常见用途:
- 微调元素位置
- 作为
absolute子元素的定位参考
2.3 absolute——绝对定位
相对于最近的非 static 祖先偏移,脱离文档流,原位置不保留空间。
.parent-abs {
position: relative;
width: 300px;
height: 200px;
background: #ecf0f1;
}
.child-abs {
position: absolute;
top: 20px;
right: 20px;
width: 80px;
height: 80px;
background: #e74c3c;
}
<div class="parent-abs">
<div class="child-abs"></div>
</div>
效果图描述:灰色容器内,红色方块紧贴右上角(距顶20px、距右20px)。 关键要点:
- 若无已定位祖先,则相对于初始包含块(通常是
<html>) - 绝对定位元素的
width: auto会收缩到内容宽度(类似浮动) - 常用于弹窗、下拉菜单、角标等
2.4 fixed——固定定位
相对于浏览器视口定位,脱离文档流,滚动页面时位置不变。
.nav-fixed {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 50px;
background: #2c3e50;
color: #fff;
z-index: 1000;
}
.back-to-top {
position: fixed;
bottom: 30px;
right: 30px;
width: 50px;
height: 50px;
background: #3498db;
border-radius: 50%;
cursor: pointer;
}
效果图描述:深色导航栏始终固定在页面顶部;蓝色圆形”回到顶部”按钮固定在右下角。 注意:
fixed元素的包含块是视口,但如果祖先设置了transform/perspective/filter,包含块会变为该祖先(这是一个常见”坑”)。
2.5 sticky——粘性定位
在特定滚动阈值内表现为 relative,超出阈值后表现为 fixed。
.section-title {
position: sticky;
top: 0;
background: #fff;
padding: 10px;
border-bottom: 2px solid #3498db;
z-index: 10;
}
<div style="height:2000px;">
<h2 class="section-title">第一章</h2>
<p>内容区域……(很长)</p>
<h2 class="section-title">第二章</h2>
<p>内容区域……(很长)</p>
</div>
效果图描述:滚动时,章节标题到达页面顶部后”粘住”,直到被下一个标题推出。 关键要点:
sticky元素不会脱离文档流- 必须指定
top/bottom/left/right中的至少一个 - 父容器的高度是 sticky 的”活动范围”,超出父容器后 sticky 失效
- 父容器不能设置
overflow: hidden/auto/scroll,否则 sticky 失效
2.6 z-index 与层叠上下文
z-index 仅对 position 非 static 的元素有效(sticky 除外,它天然创建层叠上下文)。
.layer-1 {
position: absolute;
z-index: 1;
background: rgba(231, 76, 60, 0.7);
}
.layer-2 {
position: absolute;
z-index: 10;
background: rgba(52, 152, 219, 0.7);
}
.layer-3 {
position: absolute;
z-index: 5;
background: rgba(46, 204, 113, 0.7);
}
层叠上下文的创建条件(部分):
position非static+z-index非autoopacity< 1transform非nonefilter非nonewill-change: transformdisplay: flex/grid子元素的z-index非auto[警告] 常见坑:子元素的
z-index再高,也无法超越父级层叠上下文的限制。
3. BFC(块格式化上下文)
3.1 什么是 BFC
BFC(Block Formatting Context)是 CSS 中一个独立的渲染区域,内部元素的布局不会影响外部元素。可以把它想象成一个隔离的布局容器。
3.2 BFC 的布局规则
- 内部块级盒子垂直方向一个接一个排列
- 同一个 BFC 中,相邻块级盒子的垂直外边距会发生折叠(margin collapse)
- BFC 区域不会与浮动元素重叠
- BFC 可以包含浮动元素(解决高度塌陷)
- 计算 BFC 高度时,浮动元素也参与计算
3.3 触发 BFC 的条件
| 属性 | 值 |
|---|---|
float | left / right(非 none) |
position | absolute / fixed |
display | inline-block / table-cell / table-caption / flex / inline-flex / grid / inline-grid / flow-root |
overflow | hidden / auto / scroll(非 visible) |
contain | layout / content / paint |
3.4 BFC 的典型应用
应用一:清除浮动(解决高度塌陷)
.container {
display: flow-root;
}
应用二:防止 margin 折叠
<div style="margin-bottom:20px;background:#e74c3c;">A</div>
<div style="margin-top:30px;background:#3498db;">B</div>
效果图描述:A 和 B 之间间距为 30px(取较大值),而非 50px。 解决方案:将其中一个元素包裹在 BFC 容器中:
<div style="margin-bottom:20px;background:#e74c3c;">A</div>
<div style="overflow:hidden;">
<div style="margin-top:30px;background:#3498db;">B</div>
</div>
效果图描述:A 和 B 之间间距变为 50px(20+30),margin 不再折叠。
应用三:实现自适应两栏布局
浮动元素不会与 BFC 区域重叠,利用这一点实现右侧自适应:
.left {
float: left;
width: 200px;
height: 300px;
background: #e74c3c;
}
.right {
overflow: hidden;
height: 300px;
background: #3498db;
}
<div class="left">固定宽度侧栏</div>
<div class="right">自适应内容区</div>
效果图描述:左侧红色固定 200px,右侧蓝色自动填满剩余宽度,不会跑到红色下方。
4. 传统经典布局
4.1 圣杯布局(Holy Grail Layout)
三栏布局:中间自适应,两侧固定宽度。DOM 顺序中间栏优先渲染。
.holy-grail {
padding: 0 200px 0 150px;
}
.holy-grail .center {
float: left;
width: 100%;
background: #ecf0f1;
min-height: 300px;
}
.holy-grail .left {
float: left;
width: 150px;
margin-left: -100%;
position: relative;
left: -150px;
background: #e74c3c;
min-height: 300px;
}
.holy-grail .right {
float: left;
width: 200px;
margin-left: -200px;
position: relative;
right: -200px;
background: #3498db;
min-height: 300px;
}
<div class="holy-grail clearfix">
<div class="center">Center(主内容区,优先渲染)</div>
<div class="left">Left(150px)</div>
<div class="right">Right(200px)</div>
</div>
效果图描述:三栏并排——左侧红色 150px,中间灰色自适应,右侧蓝色 200px。中间栏在 DOM 中排在最前。 核心原理:
- 三栏均左浮动,中间栏
width: 100%占满 - 左栏
margin-left: -100%移到中间栏左侧 - 右栏
margin-left: -200px移到中间栏右侧 - 父容器
padding留出两侧空间,左右栏position: relative偏移到位
4.2 双飞翼布局
与圣杯布局目标相同,但实现方式不同:中间栏内部再包一层,用 margin 留空间而非父容器 padding。
.double-wing .center-wrap {
float: left;
width: 100%;
}
.double-wing .center {
margin: 0 200px 0 150px;
background: #ecf0f1;
min-height: 300px;
}
.double-wing .left {
float: left;
width: 150px;
margin-left: -100%;
background: #e74c3c;
min-height: 300px;
}
.double-wing .right {
float: left;
width: 200px;
margin-left: -200px;
background: #3498db;
min-height: 300px;
}
<div class="double-wing clearfix">
<div class="center-wrap">
<div class="center">Center(主内容区)</div>
</div>
<div class="left">Left(150px)</div>
<div class="right">Right(200px)</div>
</div>
效果图描述:视觉效果与圣杯布局一致,但中间栏通过内部 margin 而非父容器 padding 留空间。 圣杯 vs 双飞翼对比:
对比项 圣杯布局 双飞翼布局 留空间方式 父容器 padding+ 子元素relative中间栏内部 marginDOM 层级 三栏同级 中间栏多包一层 position左右栏需要 relative不需要 relative中间栏最小宽度 受 padding约束受 margin约束
4.3 等高布局
传统方式实现多列等高:
.equal-height {
overflow: hidden;
}
.equal-height .col {
float: left;
width: 33.33%;
padding-bottom: 9999px;
margin-bottom: -9999px;
background: #ecf0f1;
}
.equal-height .col:nth-child(2) {
background: #bdc3c7;
}
.equal-height .col:nth-child(3) {
background: #95a5a6;
}
效果图描述:三列高度一致,以内容最多的列为准。利用超大
padding-bottom+ 负margin-bottom实现。
5. 居中方案汇总
5.1 水平居中
行内元素 / 行内块元素
.parent {
text-align: center;
}
<div class="parent">
<span>行内元素居中</span>
</div>
定宽块级元素
.child {
width: 200px;
margin: 0 auto;
}
不定宽块级元素
.parent {
text-align: center;
}
.child {
display: inline-block;
}
5.2 垂直居中
单行文本
.single-line {
height: 50px;
line-height: 50px;
}
多行文本(table-cell)
.parent {
display: table-cell;
vertical-align: middle;
height: 200px;
}
绝对定位 + transform
.parent {
position: relative;
height: 200px;
}
.child {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
5.3 水平垂直居中
方案一:绝对定位 + transform(最经典)
.parent {
position: relative;
width: 400px;
height: 300px;
background: #ecf0f1;
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: #e74c3c;
padding: 20px;
color: #fff;
}
效果图描述:红色方块精确居中在灰色容器正中央。 优点:无需知道子元素尺寸。缺点:
transform可能影响子元素的fixed定位。
方案二:绝对定位 + 负 margin(需已知尺寸)
.child {
position: absolute;
top: 50%;
left: 50%;
width: 200px;
height: 100px;
margin-top: -50px;
margin-left: -100px;
}
优点:兼容性极好。缺点:需要知道子元素宽高。
方案三:绝对定位 + margin: auto(需已知尺寸)
.child {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
width: 200px;
height: 100px;
}
原理:绝对定位元素四边为 0 时,浏览器自动计算 margin 使其居中。
方案四:table-cell
.parent {
display: table-cell;
vertical-align: middle;
text-align: center;
width: 400px;
height: 300px;
}
.child {
display: inline-block;
}
优点:兼容 IE8+。缺点:display: table-cell 对布局有限制。
方案五:Flexbox(现代推荐 [完成])
.parent {
display: flex;
justify-content: center;
align-items: center;
height: 300px;
}
优点:最简洁,无需知道子元素尺寸。缺点:IE9 及以下不支持。
方案六:Grid(最现代)
.parent {
display: grid;
place-items: center;
height: 300px;
}
优点:代码最少。缺点:IE 不支持。
5.4 居中方案对比总结
| 方案 | 需知尺寸 | 兼容性 | 代码量 | 适用场景 |
|---|---|---|---|---|
| absolute + transform | [错误] | IE10+ | 少 | 通用 |
| absolute + 负 margin | [完成] | IE6+ | 中 | 已知尺寸 |
| absolute + margin:auto | [完成] | IE8+ | 少 | 已知尺寸 |
| table-cell | [错误] | IE8+ | 多 | 兼容旧浏览器 |
| Flexbox | [错误] | IE10+ | 少 | 现代项目首选 |
| Grid | [错误] | 现代浏览器 | 最少 | 最新项目 |
6. 总结
虽然现代开发推荐使用 Flex/Grid,但理解 Float 和 Position 对维护旧项目和处理特定定位需求(如固定导航栏、弹窗)依然至关重要。 关键要点回顾:
- 浮动:图文环绕 → 布局 → 高度塌陷 → clearfix / flow-root
- 定位:static(默认)→ relative(微调/参照)→ absolute(脱离流/弹窗)→ fixed(视口固定)→ sticky(滚动粘性)
- BFC:隔离布局容器,解决塌陷/margin 折叠/自适应两栏
- 经典布局:圣杯/双飞翼是浮动布局的巅峰应用
- 居中:从传统 hack 到 Flex/Grid,方案越来越简洁
更新日志 (Changelog)
- 2026-05-27: v1.0.0 大幅扩充——新增 BFC 详解、圣杯/双飞翼布局、居中方案汇总、z-index 层叠上下文、sticky 注意事项
- 2026-04-05: 整合传统布局与现代定位技巧