CSS 定位属性完全指南:relative、absolute、fixed、sticky 详解
Introduction
CSS position 属性是控制元素定位的核心属性,决定了元素相对于其父容器、视口或其他已定位祖先元素的排列方式。掌握 position 的四种定位模式(static/relative/absolute/fixed)以及 CSS3 新增的 sticky,是实现吸顶导航、弹出层、回到顶部、侧边栏跟随等常见交互效果的基础。
四种定位模式
/* static(默认值):正常文档流定位 */
div { position: static; top: 100px; /* 无效,static 下 top 无意义 */ }
/* relative:相对自身原始位置定位,保留原位置占用 */
.box { position: relative; top: 20px; left: 30px; }
/* 元素仍在原位,但视觉上向下向右偏移 20px/30px */
/* absolute:相对最近已定位祖先元素定位,完全脱离文档流 */
.parent { position: relative; }
.child { position: absolute; top: 0; right: 0; }
/* 相对于 .parent 定位在右上角,如果无已定位祖先则相对于 body */
/* fixed:相对于视口定位,滚动页面也固定不动 */
.back-to-top { position: fixed; bottom: 30px; right: 30px; }
/* 固定在页面右下角,滚动时位置不变 */
z-index 层级控制
/* 只有已定位元素(非 static)才能用 z-index */
.modal-overlay { position: fixed; z-index: 1000; }
.modal-content { position: absolute; z-index: 1001; /* 比 overlay 高 */ }
/* z-index 的层叠上下文(stacking context)*/
.parent { position: relative; z-index: 1; }
.child { position: absolute; z-index: 100; /* 即使数值大,也被父元素的 z-index 限制 */ }
/* 负值 z-index */
.behind { position: absolute; z-index: -1; /* 在父元素后面 */ }
sticky 定位(CSS3 新增)
/* sticky:滚动到阈值前表现为 relative,超过阈值后变为 fixed */
.sticky-header {
position: sticky;
top: 0; /* 滚动到离视口顶部 0px 时固定 */
background: #fff;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
/* 左侧吸边 */
.sidebar {
position: sticky;
top: 20px;
align-self: flex-start; /* Flex 容器中使用 */
}
/* 注意:sticky 需要父容器有明确高度,且 overflow 不是 visible */
实战:经典布局技巧
/* 1. 居中弹窗 */
.modal {
position: fixed;
inset: 0; /* top:0; right:0; bottom:0; left:0; */
display: flex;
align-items: center;
justify-content: center;
}
/* inset: 0 + margin: auto 也能居中 */
.modal-box {
position: absolute;
top: 50%; left: 50%;
transform: translate(-50%, -50%); /* 居中偏移 */
}
/* 2. 绝对定位下拉菜单 */
.dropdown { position: relative; }
.dropdown-menu {
position: absolute;
top: 100%;
left: 0;
min-width: 200px;
display: none;
}
.dropdown:hover .dropdown-menu { display: block; }
运行效果
打开固定头部示例,页面向上滚动时导航栏自动吸顶;回到顶部按钮始终固定在右下角;弹窗无论页面滚动到什么位置都居中显示,不会随页面消失。
常见问题
- absolute 相对于谁定位:相对于最近一个 position 值不为 static 的祖先元素(已定位祖先)。如果没有任何已定位祖先,则相对于初始包含块(通常是 body)。
- z-index 不生效:检查元素是否设置了 position(非 static)。有时是父元素的 z-index 或 opacity/transform 形成了层叠上下文,限制了子元素的层级。
- sticky 失效:常见原因是父元素 overflow 不是 visible(auto/hidden 会破坏 sticky 行为),或者父容器高度不够。
- fixed 与 transform:当元素祖先有 transform 属性(非 none)时,fixed 定位相对于该祖先而非视口(某些浏览器行为)。
- MDN position 属性:MDN position
- 层叠上下文详解:MDN 理解 z-index
- sticky 定位浏览器兼容性:iOS Safari 6+ 支持