背景:给 PaperMod 博客做「左侧悬浮目录」时,从 fixed 迁移到 sticky,系统梳理了 position 的完整体系。


一、一句话总纲

position 决定了一个元素"相对于谁、用什么规则来定位"。

CSS 里有 5 个值(其中 4 个常用)。它们最大的区别,就在两个问题:

  1. 参照物是谁 —— 相对自己?相对祖先?相对屏幕?
  2. 会不会脱离文档流 —— 原来的位置还占不占?

二、先理解前提:什么是「文档流」

  • 网页元素默认从上到下、从左到右自然排列,像写字一样一行行排下来。
  • 这个「自然的排列规则」就叫文档流(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:relativeabsolute 的「锚点」

一个 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