← 返回题目列表

CSS position 有哪些取值?relative、absolute、fixed、sticky 有什么区别?

高频 中等 第 13 / 28 题 更新于 2026/07/27
CSSposition定位

简化版

position 控制元素定位方式。static 是默认流式布局;relative 相对自身原位置偏移且保留占位;absolute 相对最近定位祖先定位并脱离文档流;fixed 相对视口固定;sticky 在普通流和固定定位之间切换。

详细版

常见取值:

  • static:默认值,top/right/bottom/left 不生效。
  • relative:相对自身原位置偏移,不脱离文档流。
  • absolute:相对最近非 static 祖先定位,脱离文档流。
  • fixed:相对视口定位,脱离文档流,常用于悬浮按钮、固定头部。
  • sticky:滚动到阈值前按普通流布局,达到阈值后像 fixed 一样粘住。

面试重点是 containing block:absolute 不一定相对父元素,而是相对最近有定位的祖先;如果没有,就相对初始包含块。工程里常给父元素加 position: relative,让子元素绝对定位有参照物。

完整版教学

一、relative 的特点

relative 会保留元素在普通文档流里的位置,然后视觉上偏移。

.badge {
  position: relative;
  top: -4px;
}

它常用于小范围微调,也常作为 absolute 子元素的定位上下文。注意:偏移后的元素可能覆盖别人,但原来的占位还在。

二、absolute 的参照物

absolute 会脱离普通文档流,不再占据原来的空间。它的定位参照物是最近的“定位祖先”,也就是 position 不为 static 的祖先。

.card {
  position: relative;
}
.close {
  position: absolute;
  top: 8px;
  right: 8px;
}

如果 .card 没有 position: relative,关闭按钮可能跑到页面其他参照物上,这就是很多定位 bug 的来源。

三、fixed 和 transform 的特殊问题

fixed 通常相对视口定位,但如果祖先元素设置了某些属性,比如 transformfilterperspective,可能会创建新的包含块,让 fixed 表现得像相对这个祖先固定。

这在弹窗、抽屉、移动端页面里很常见。遇到 fixed 不按视口固定,可以检查祖先是否有 transform。

四、sticky 的生效条件

sticky 必须配合阈值,比如 top: 0。它还受滚动容器影响,粘住的是最近滚动祖先,不一定是整个窗口。

.toc {
  position: sticky;
  top: 80px;
}

如果 sticky 不生效,常见原因是父容器高度不够、祖先设置了不合适的 overflow、没有设置 top/bottom 阈值。

五、面试追问与工程落地

定位题经常会追问 z-indexz-index 不是一个全页面绝对数字,它只在同一个层叠上下文里比较。position 配合 z-indexopacity < 1transformfilter 等都可能创建新的层叠上下文。一个元素 z-index: 9999 仍然可能被另一个上下文里的元素盖住。

还要注意 absolute 的包含块不只由 position 决定。某些 CSS 属性如 transform 也会影响 fixed 或 absolute 的定位参照。实际遇到弹窗位置异常、固定按钮跟着某个容器走,应该检查祖先元素是否创建了新的 containing block。

工程建议是:组件内部的小角标、关闭按钮,用父级 position: relative 加子级 absolute;全局弹窗、toast、dropdown 更推荐统一挂到顶层容器,避免被局部 overflow、transform、z-index 上下文限制。

六、用两条轴和包含块推导定位结果

面试给出定位代码时,先确定元素是否脱离普通流,再找包含块,最后分别计算 inline 轴和 block 轴的 inset。假设定位祖先 padding box 为 600 × 400px,子元素为 120 × 80px,写 left: 50%; top: 50% 时子元素左上角落在 (300, 200);再加 translate(-50%, -50%) 后各减自身一半,最终左上角为 (240, 160)

是否保留普通流占位常见定位参照典型用途
static所在格式化上下文普通内容
relative自身原始位置微调、建立定位包含块
absolute最近的绝对定位包含块角标、组件内浮层
fixed通常是视口,也可能是祖先包含块全局悬浮控件
sticky最近滚动容器的滚动口并受包含块约束吸顶标题、目录

absolute “相对最近非 static 祖先”是常用简化说法;严谨判断还要检查 transform、contain、will-change 等会建立定位包含块的属性。

七、常见误区与追问

  • 误区:absolute 一定相对直接父元素定位。 它寻找最近建立相应包含块的祖先,直接父元素若未建立包含块就会继续向上查找。
  • 误区:fixed 在任何情况下都只相对浏览器视口。 某些祖先的 transformcontainwill-change 能建立 fixed positioning containing block。
  • 误区:z-index: 999999 一定能盖住所有元素。 z-index 先在各自层叠上下文内排序,子元素无法用大数字越过祖先所在的上下文层级。
  • 追问:relative 偏移后会挤开相邻元素吗? 不会重新安排相邻盒,它保留原占位并做视觉偏移,但可能扩大祖先的可滚动溢出区域。
  • 追问:sticky 什么时候开始粘住? 当滚动使盒子越过指定的非 auto inset 阈值时,它相对最近滚动口调整位置,同时仍受自身包含块边界限制。
  • 追问:为什么 sticky 在短父容器里看不出效果? 它不能无限越过包含块;若可滚动距离或父级可用范围不足,粘滞阶段会很短甚至不可见。
  • 追问:全局弹窗为什么常用 portal 挂到页面顶层? 这样可以减少局部 overflow 裁剪、transform 包含块和层叠上下文对定位与覆盖关系的干扰。

八、加强记忆

定位可以按“是否脱离文档流”和“相对谁定位”记:relative 不脱流、相对自己;absolute 脱流、找定位祖先;fixed 脱流、通常看视口;sticky 先在流里,滚到阈值再粘住。