讲解
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 与层叠上下文。