position 五取值
基于 CSS 现代标准 · 核于 2026-06
速查
static:默认值,元素在正常流里,top/right/bottom/left/z-index全部无效relative:在正常流里占位不变,仅视觉上按top/left偏移;不影响兄弟;常用作absolute子元素的参照系absolute:脱离正常流(原位不占空间),相对最近的已定位祖先(position非static)的内边距盒定位;无定位祖先则相对初始包含块(视口)fixed:脱流,相对视口定位、滚动不动;例外:祖先有transform/filter/perspective(非none)会夺走包含块,使fixed相对该祖先sticky:正常流内,滚动到阈值前同relative,越过后吸在滚动容器边界;必须设至少一个top/bottom/left/rightinset简写 =top right bottom left(同margin顺序);inset: 0撑满包含块;逻辑写法inset-block-start等适配 RTL- 同时写对向 inset(
top+bottom且height:auto)→ 元素被拉伸填满;冲突且尺寸固定 →top/left胜(LTR) - 层叠上下文:
relative/absolute仅z-index≠auto时创建;fixed/sticky只要定位就创建 sticky三大失效:①忘写阈值;②父级overflow非visible抢成滚动容器;③父级高度不足无可吸空间- Baseline:
position五取值均 Widely available(2015-07 起广泛可用),放心用
static:默认的正常流
每个元素的初始 position 都是 static——它老老实实待在正常流里,top/right/bottom/left 和 z-index 写了也完全没用。所以「我设了 z-index 怎么不生效」第一件事就是检查:这个元素定位了吗?
.box {
/* position: static 是默认值 */
top: 50px; /* ← 无效 */
z-index: 10; /* ← 无效 */
}只有当 position 变成 relative / absolute / fixed / sticky 之一(统称「定位元素」),偏移与 z-index 才开始工作。
relative:相对自己,原位仍占
relative 是最温和的定位:元素仍在正常流里、原来的位置仍然占着,只是视觉上按 top/left 等偏移挪动,不影响任何其他元素。
.tweak {
position: relative;
top: -2px; /* 视觉上抬高 2px,但它原来的格子还空在那 */
}它有两个核心用途:
- 微调:让某元素相对原位轻微位移(如对齐图标基线);
- 当参照系:给它加上
position: relative但不写任何偏移,把它变成内部absolute子元素的「定位锚」——这是定位里最高频的用法。
.card {
position: relative; /* 不偏移,只为把坐标系交给子元素 */
}
.card__close {
position: absolute;
top: 8px;
right: 8px;
}relative 仍占位带来的「幽灵空白」
因为 relative 偏移后原位仍占空间,把元素挪开后,原处会留下一块「看不见但占着」的空白,后面元素不会顶上来。需要元素挪走且后续元素补位时,应该用 absolute(脱流)而非 relative。
absolute:脱流,相对最近定位祖先
absolute 把元素彻底移出正常流——原来的位置不再保留,后续元素会顶上来,仿佛它不存在。它的定位参照是最近的「已定位」祖先(position 计算值为 relative/absolute/fixed/sticky 的祖先)的内边距盒;若一路向上找不到任何已定位祖先,则相对初始包含块(ICB),也就是视口大小的根。
.menu {
position: relative; /* 关键:给下拉一个参照 */
}
.menu__dropdown {
position: absolute;
top: 100%; /* 紧贴菜单底部 */
left: 0;
width: 200px;
}几个要点:
- 尺寸:
width/height为auto时按内容收缩(shrink-to-fit),而非撑满父级; - 撑满技巧:同时写
top:0; bottom:0(保持height:auto)可纵向填满包含块,left:0; right:0则横向填满;inset: 0一次撑满四边; - 外边距不折叠:绝对定位盒的 margin 不与其他元素的 margin 合并;
- 层叠上下文:仅当
z-index不为auto时才创建新层叠上下文。
找错包含块是 absolute 第一大坑
如果忘了给最近的预期父级加 position: relative,浏览器会继续往上找,可能一路找到 <body> 甚至视口——于是你的角标跑到了页面左上角。排查 absolute 位置不对时,先确认「我想让它相对谁,那个谁定位了吗」。
fixed:相对视口,滚动不动
fixed 同样脱离正常流,但参照物通常是视口——页面怎么滚,它都钉在屏幕同一处。吸顶导航、右下角「回到顶部」、全屏遮罩都靠它。
.back-to-top {
position: fixed;
right: 24px;
bottom: 24px;
}它在打印时会出现在每一页的同一位置(视为分页媒介的固定块)。
fixed 的致命例外:被祖先的 transform 夺走
这是面试与实战的双料高频坑。MDN 明确:
若任一祖先的
transform、perspective或filter属性被设为非none的值,该祖先会取代视口成为fixed元素的包含块。
也就是说,下面这段里 .modal 不再相对视口,而是相对 .page,top: 0 指的是 .page 的顶部而非屏幕顶部:
.page {
transform: translateZ(0); /* 哪怕只是「触发 GPU 层」这种无害写法 */
}
.modal {
position: fixed;
inset: 0; /* 本想铺满屏幕,结果只铺满了 .page */
}能夺走 fixed 包含块的属性还包括 will-change: transform、filter、backdrop-filter、contain: paint/layout/strict/content 等。排查「fixed 怎么跟着滚 / 怎么没铺满屏幕」时,沿 DOM 往上找有没有祖先设了这些属性。它始终创建层叠上下文(与 z-index 无关)。
sticky:流内吸附,越界即停
sticky 是「relative 与 fixed 的混血」:默认像 relative 一样待在正常流里随页面滚动;一旦滚动到你指定的阈值(如 top: 0),它就「吸住」、像 fixed 一样停在滚动容器的边上;直到它的**包含块(父级)**整体滚出视野,它又随父级一起离开。经典用途是吸顶表头、分组标题、侧栏吸附。
.section-heading {
position: sticky;
top: 0; /* 滚到顶时吸住;没有这一行,sticky 形同 relative */
background: var(--bg); /* 吸住时盖住下方内容,记得给背景 */
}sticky 三大「静默失效」
sticky 不报错,失效时只是「没吸住」,排查靠经验。三大主因:
忘了写阈值。
position: sticky必须在需要吸附的轴上设至少一个top/bottom/left/right(非auto)作为「触发线」。该轴上四个偏移全auto时,sticky退化为普通relative,永远不吸。父级
overflow抢成了滚动容器。MDN 原文:粘性元素「吸附」于其最近的、带有「滚动机制」的祖先(当
overflow为hidden、scroll、auto或overlay时产生),即便该祖先并非最近的实际滚动祖先。这意味着:只要某个父级设了
overflow: hidden(哪怕只是为了清浮动或裁圆角),sticky就会以那个父级为参照——而那个父级往往自身不滚动,于是sticky像被钉死,看起来「没生效」。这是最隐蔽的一种失效。父级高度不足。
sticky只能在它的包含块(父级)范围内吸附。如果父级高度恰好等于(或小于)粘性元素自身高度,就没有「可供滑动吸附」的空间,元素从头到尾都贴着,看不出吸附效果。要让吸顶表头一路跟随,须保证它的父容器足够高。
sticky 自查清单
吸不住时,依次核对:①该轴上写阈值了吗(top/bottom/…)?②从它到滚动区之间,有没有父级设了 overflow: hidden/auto/scroll?③它的直接父级是否足够高?④是不是想吸附在 <thead>/<tr> 上但表格布局限制了它(给 th/td 而非 tr 设 sticky 更稳)?sticky 始终创建层叠上下文。
inset 与逻辑偏移
四个物理方向可用 inset 简写(顺序同 margin:上、右、下、左):
.fill { position: absolute; inset: 0; } /* 撑满 */
.corner { position: fixed; inset: 12px 12px auto auto; } /* 钉右上 */需要随书写方向自适应时,用逻辑属性 inset-block-start(块向起点)、inset-inline-end(行向终点)等——它们在 RTL 语言或竖排文字下会自动翻转,比写死 left/right 更稳健。
小结
static 不可定位,relative 原位微调兼作参照,absolute 脱流找最近定位祖先,fixed 钉视口但怕祖先 transform,sticky 流内吸附却怕没阈值和父级 overflow。摆好了位置,下一个问题就是元素重叠时谁压谁——进入最常被误解的 z-index 与层叠上下文。