背景:给 PaperMod 博客做「左侧悬浮目录」时,从
fixed迁移到sticky,系统梳理了position的完整体系。
一、一句话总纲
position决定了一个元素"相对于谁、用什么规则来定位"。
CSS 里有 5 个值(其中 4 个常用)。它们最大的区别,就在两个问题:
- 参照物是谁 —— 相对自己?相对祖先?相对屏幕?
- 会不会脱离文档流 —— 原来的位置还占不占?
二、先理解前提:什么是「文档流」
- 网页元素默认从上到下、从左到右自然排列,像写字一样一行行排下来。
- 这个「自然的排列规则」就叫文档流(normal flow)。
- 默认情况(
position: static),所有元素都待在文档流里,一个接一个。
position 的很多值,本质就是"让元素脱离这个自然流,然后相对某个参照物重新定位"。
三、五个值逐个拆解
1. static(默认值)
.element { position: static; }
- 所有元素的默认状态,不写
position就是它。 - 元素乖乖待在文档流里,按顺序排列。
top/left/right/bottom这些偏移属性对它无效。
一句话:就正常排着,别动我。
2. relative(相对定位)
.element { position: relative; top: 10px; left: 20px; }
- 相对它自己原来的位置偏移。
- 关键点 1:仍然占着原来的位置(不脱离文档流,坑还在)。
- 关键点 2:
top: 10px= 从原位置往下挪 10px;left: 20px= 往右挪 20px。
一句话:我人挪了,但原来的座位还给我留着。
隐藏但极重要的用途:
relative可以当「定位锚点」——一个relative元素,会成为它内部absolute元素的参照物。这是它最常见的使用方式。
3. absolute(绝对定位)
.element { position: absolute; top: 0; right: 0; }
- 完全脱离文档流,原来的位置被后面的元素顶上(不留坑)。
- 参照物:最近的、带
position的祖先元素(通常是relative的父容器)。 - 如果没有任何带
position的祖先,就相对整个页面(body)定位。
一句话:我飘起来了,谁也别占我的座;我贴着最近那个被标记的祖先来定位。
4. fixed(固定定位)
.element { position: fixed; top: 0; left: 0; }
- 完全脱离文档流。
- 参照物:浏览器窗口(屏幕),永远相对屏幕定位。
- 页面怎么滚动,它都固定在屏幕上不动。
一句话:我钉在屏幕上了,不管页面怎么滚,我都在这里。
5. sticky(粘性定位)
.element { position: sticky; top: 80px; }
- relative 和 fixed 的混合体。
- 平时表现像
relative(待在文档流里,占位置)。 - 当滚动到某个临界点(如
top: 80px)时,临时表现像fixed,粘在屏幕上不动。 - 关键约束:只在父容器范围内粘住,滚出父容器就不粘了。
一句话:平时老实待着,滚到临界点就粘住,但只在爸妈(父容器)怀里粘。
四、一张表牢牢记住
| position | 参照物(相对谁定位) | 脱离文档流吗 | 一句话 |
|---|---|---|---|
static | 无(就正常排) | 否 | 默认状态,别动我 |
relative | 自己原来的位置 | 否(占坑) | 挪了人,坑还留着 |
absolute | 最近的 position 祖先 | 是 | 飘起来,贴祖先 |
fixed | 浏览器窗口(屏幕) | 是 | 钉在屏幕上 |
sticky | 父容器(滚动时) | 否(占坑,临界时粘住) | relative + fixed 混合 |
五、两个最重要的「关系」
关系 1:relative 是 absolute 的「锚点」
一个 absolute 元素,会去找「最近的、带 position 的祖先」当参照物。而人们通常给那个祖先设 position: relative(因为它相对自己不动,正好当个稳定锚点)。
经典组合:
父容器 { position: relative; } /* 当锚点 */
子元素 { position: absolute; } /* 相对父容器定位 */
关系 2:sticky = relative + fixed 的「混血儿」
- 平时像
relative:待在文档流里,占着位置。 - 滚到临界点时像
fixed:粘在屏幕上。 - 但只能在父容器范围内粘,滚出父容器就恢复成普通流。
这就是为什么 sticky 目录能「跟随滚动」,但不会像 fixed 那样跑出正文范围。
六、回到我们的博客场景
为什么之前用 fixed 会出问题、现在要转向 sticky:
fixed目录 = 相对屏幕固定 → 和居中的正文「脱节」,窄屏时压字。sticky目录 = 相对正文容器粘住 → 跟着正文走,天然不脱节。
七、速记关键词
- 文档流:元素默认的上下排列规则。
- 参照物:position 最核心的区别,就是「相对谁定位」。
- relative:相对自己,占坑,可当锚点。
- absolute:相对最近 position 祖先,脱离流。
- fixed:相对屏幕,脱离流,钉死不动。
- sticky:relative + fixed 混合,父容器内粘住。
- 经典组合:父
relative+ 子absolute。