CSS定位与层级
# 04.CSS定位与层级
五种 position 全解(static/relative/absolute/fixed/sticky)、z-index 层叠规则、层叠上下文的创建条件与比较逻辑、containing block 对 absolute 定位的隐性影响。
# 1. 五种 position
.static { position: static; } /* 默认:正常文档流 */
.relative { position: relative; } /* 相对自身偏移,不脱离文档流 */
.absolute { position: absolute; } /* 相对于最近的定位祖先,脱离文档流 */
.fixed { position: fixed; } /* 相对于视口,脱离文档流 */
.sticky { position: sticky; } /* 滚动到阈值后固定 */
# 1.1 static(默认)
元素按正常文档流排列,top/right/bottom/left 和 z-index 无效。
# 1.2 relative — 相对定位
.box {
position: relative;
top: 10px; /* 向下偏移 10px */
left: 20px; /* 向右偏移 20px */
}
关键特征:
- 不脱离文档流(原位置仍被占据)
- 偏移量相对于自身原位置
- 常作为
absolute子元素的定位参考(设置position: relative而不给偏移量)
# 1.3 absolute — 绝对定位
.child {
position: absolute;
top: 0;
right: 0;
}
关键特征:
- 脱离文档流(原位置被后续元素占据)
- 相对于最近的
position ≠ static的祖先元素定位 - 若无定位祖先 → 相对于
<body>(首次包含块)
<div class="parent" style="position: relative;"> <!-- 定位参考 -->
<div class="child" style="position: absolute; top: 0; right: 0;">
右上角
</div>
</div>
# 1.4 fixed — 固定定位
.modal-overlay {
position: fixed;
top: 0; right: 0; bottom: 0; left: 0; /* 全屏覆盖 */
background: rgba(0,0,0,0.5);
}
关键特征:
- 相对于浏览器视口定位(不随滚动条移动)
- 例外:若祖先元素有
transform/filter/perspective,则相对于该祖先
# 1.5 sticky — 粘性定位
.header {
position: sticky;
top: 0; /* 滚动到顶部时固定 */
}
.sidebar {
position: sticky;
top: 80px; /* 距顶部 80px 时开始固定 */
}
sticky = relative + fixed 的混合:
- 未到阈值时:表现为
relative - 到达阈值后:表现为
fixed(但限于父容器内)
失效条件:
- 父容器设置了
overflow: hidden/scroll/auto - 父容器高度不足以触发滚动
- 未指定
top/right/bottom/left中至少一个
# 2. z-index 与层叠上下文
# 2.1 z-index 基本规则
.box1 { z-index: 10; }
.box2 { z-index: 20; } /* box2 显示在 box1 上方 */
- z-index 只对定位元素(
position ≠ static)或 flex/grid 子项生效 - 默认值
auto(相当于 0,但不创建层叠上下文) - 相同值 → 按 DOM 顺序,后写的在上
# 2.2 层叠上下文的创建
以下属性会创建新的层叠上下文:
| 触发方式 | 常用场景 |
|---|---|
position: relative/absolute/fixed/sticky + z-index ≠ auto | 最传统 |
opacity < 1 | 半透明遮罩 |
transform: none 以外 | 动画元素 |
filter 任意值 | 滤镜效果 |
will-change: transform / opacity | 性能优化 |
isolation: isolate | 专门用来创建层叠上下文 |
# 2.3 层叠比较规则
同一层叠上下文中,按以下顺序从下到上排列:
① 根层叠上下文的 background 和 border
② z-index < 0 的定位元素
③ 正常文档流中的块级元素
④ 正常文档流中的浮动元素
⑤ 正常文档流中的行内元素
⑥ z-index: 0 / auto 的定位元素
⑦ z-index > 0 的定位元素
# 2.4 常见坑
/* 坑 1:子元素的 z-index 不能突破父层叠上下文 */
.parent { z-index: 1; position: relative; } /* 创建层叠上下文 */
.child { z-index: 999; position: absolute; } /* 这个 999 仅在 parent 内有意义 */
/* 坑 2:opacity < 1 意外创建层叠上下文 */
.fade-box { opacity: 0.99; } /* z-index 行为发生变化 */
/* 坑 3:transform 同样创建层叠上下文 */
.animated { transform: translateX(0); } /* fixed 子元素定位失效 */
# 2.5 实战:弹窗蒙层的正确层级
.modal-backdrop {
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
z-index: 1000; /* 蒙层在底层 */
background: rgba(0,0,0,0.5);
}
.modal-content {
position: fixed;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
z-index: 1001; /* 弹窗内容在蒙层之上 */
}
# 3. containing block(包含块)
absolute 元素的定位参考不是父元素,而是包含块。包含块的确定规则:
| position | 包含块 |
|---|---|
| static / relative | 最近的块级祖先的 content-box |
| absolute | 最近的 position ≠ static 的祖先的 padding-box |
| fixed | 视口(例外:有 transform 的祖先) |
| sticky | 最近的滚动祖先 |
/* absolute 定位以 padding-box 为基准,不是 border-box */
.parent {
position: relative;
border: 20px solid red;
}
.child {
position: absolute;
top: 0; left: 0; /* 定位在 padding 内侧,不是 border 外侧 */
}
# 4. 速查表
| 需求 | 方案 |
|---|---|
| 元素不脱离文档流偏移 | position: relative |
| 相对父元素定位 | 父 position: relative + 子 position: absolute |
| 固定于视口 | position: fixed |
| 滚动吸顶 | position: sticky; top: 0 |
| 弹窗层级管理 | 蒙层 z-index: 1000 + 内容 z-index: 1001 |
| z-index 不生效 | 检查是否创建了层叠上下文(transform/opacity 等) |
下一篇:05.CSS动画与过渡 — transition、@keyframes 动画、GPU 加速法则。
上次更新: 2026/06/24, 10:13:05