讲解

position 属性让元素脱离常规文档流的摆布,有五个值。static 是默认值,即不定位。relative(相对定位)相对自己「原本的位置」偏移,关键点:偏移后原来的空间仍然保留,周围元素不受影响,常用来微调位置,更常见的身份是「给 absolute 后代当参照物」。absolute(绝对定位)彻底脱离文档流,不占地、相对「最近的已定位祖先」(position 不是 static 的祖先)定位,一个都没有就相对初始包含块(近似视口/页面)。它是做角标、悬浮按钮、弹层的主力。

fixed(固定定位)相对视口定位,滚动页面也不动,做吸顶导航、回到顶部按钮。注意一个现代陷阱:祖先元素一旦带了 transform、filter 或 perspective,fixed 元素的参照物就从视口变成那个祖先——弹窗突然跟着内容滚走,多半是这个原因。sticky(粘性定位)是 relative 和 fixed 的混合体:在阈值内像 relative 一样随流滚动,滚过阈值就「粘」在指定位置(如 top: 0),做分组列表的吸顶字母条、表头吸顶非常方便,但必须设置至少一个方向的阈值才生效。

偏移用 top/right/bottom/left 四个属性(或简写 inset),其正负方向容易记反:top: 10px 是「距离参照物顶边 10px」,即向下移。绝对定位元素同时设 left 和 right(或配合 inset: 0)可以不写宽高直接拉伸铺满参照物,这是做全屏蒙层的标准手法。

示例

/* 卡片角标:父 relative 当参照,子 absolute 贴角落 */
.card {
  position: relative;
}
.card .corner-badge {
  position: absolute;
  top: 8px;
  right: 8px;
  background: #fa5252;
  color: #fff;
  border-radius: 999px;
  padding: 2px 10px;
}

/* 全屏蒙层:fixed + inset 拉伸铺满视口 */
.modal-mask {
  position: fixed;
  inset: 0; /* 等价 top/right/bottom/left 全 0 */
  background: rgb(0 0 0 / 50%);
}

/* 吸顶导航与回到顶部 */
.navbar {
  position: sticky;
  top: 0;
  background: #fff;
}
.back-to-top {
  position: fixed;
  right: 24px;
  bottom: 24px;
}

/* 微调:相对自己原位置下移 2px,不推开任何人 */
.icon-aligned {
  position: relative;
  top: 2px;
}

常见坑

  • absolute 元素飞到天外:忘了给祖先设 position: relative,元素相对整个页面定位,出现在奇怪的地方。口诀:「子绝父相」——子元素 absolute,父元素 relative。
  • sticky 不粘:三个高频原因——没写 top 等阈值;某个祖先有 overflow: hidden/auto/scroll(它变成了滚动容器);父元素高度和 sticky 元素一样高,没有可滑动的区间。
  • fixed 元素会跟着滚:祖先带了 transform/filter/perspective,fixed 的参照物被「劫持」。把 fixed 弹层挪到 body 直接子级(或 teleport 到 body)最稳。
  • 偏移方向记反:top: 10px 是向下、left: -10px 是向左,记成「距离某条边多远」就不会错。
  • 脱离文档流后父容器塌陷:子元素全部 absolute 后父元素高度变 0(absolute 不占地)。要么给父元素固定高度,要么改用其他布局。

小结

relative 微调兼当参照物、absolute 相对最近定位祖先、fixed 钉在视口、sticky 滚过阈值再粘住;inset 拉伸做蒙层。定位引入了前后遮挡问题,下一章专门讲 z-index 与层叠上下文。