CSS 定位(position)

定位用来精确控制元素的位置——做弹窗、吸顶导航、tooltip、徽标都靠它。理解五种 position 取值的区别,能解决大部分"叠层"问题。但记住一条原则:能用文档流解决的,就别用定位——定位容易让代码变难维护。

1. 五种取值一览

position 属性有五个取值,核心区别在于"参照谁定位"和"是否脱离文档流"。

/* static:默认值,按文档流排,top/left 无效 */
.normal { position: static; }

/* relative:相对原本位置偏移,不脱离文档流 */
.pushed {
  position: relative;
  top: 10px;       /* 从原位置向下移 10px */
  left: 20px;      /* 向右移 20px */
}

/* absolute:脱离文档流,相对最近的"非 static 祖先"定位 */
.tooltip {
  position: absolute;
  top: 100%;      /* 父元素底部 */
  left: 0;
}

/* fixed:相对浏览器窗口,滚动不跟随 */
.modal {
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;
  background: rgba(0,0,0,.5);
}

/* sticky:滚到指定位置时"吸住" */
.nav {
  position: sticky;
  top: 0;          /* 滚到距顶 0 时吸住 */
}

简单对比:

2. relative + absolute 黄金组合

这是定位最常用的模式——父元素设 relative,子元素设 absolute。这样子元素就以父元素为参照定位,不会"乱跑"。

.container {
  position: relative;   /* 关键:作为子元素 absolute 的参照系 */
}

.badge {
  position: absolute;
  top: -8px;       /* 在父元素左上角上方一点 */
  right: -8px;
  background: #ff5722;
  color: #fff;
  border-radius: 50%;
  width: 20px;
  height: 20px;
  text-align: center;
  line-height: 20px;
  font-size: 12px;
}

典型场景:卡片右上角的小红点徽标(消息数)、图片上的标签、按钮上的 tooltip。父 relative 子 absolute 是前端开发的高频套路,务必背下来。

注意:父元素如果不设 relative,子元素的 absolute 会"逃出"父级,相对更外层的非 static 祖先定位——这是新手最常踩的坑。看到 absolute 元素位置不对,先检查父级有没有 relative。

3. fixed + 全屏弹窗

fixed 相对浏览器窗口定位,适合做全屏遮罩 + 居中弹窗的经典组合。

/* 全屏遮罩 + 居中弹窗,经典组合 */
.overlay {
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;   /* 铺满视口 */
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.modal {
  background: #fff;
  padding: 24px;
  border-radius: 12px;
  max-width: 90%;
  width: 400px;
}

关键点:

4. sticky 吸顶导航

sticky 是相对较新的取值,解决了"滚动到某位置就吸住"的需求——以前要靠 JS 监听滚动事件才能实现。现在一行 CSS 搞定。

/* 吸顶导航:滚动到顶部时贴住 */
.header {
  position: sticky;
  top: 0;
  background: #fff;
  z-index: 100;
  box-shadow: 0 2px 8px rgba(0,0,0,.05);
}

/* 注意:sticky 的父元素高度必须比 sticky 元素高,否则没空间"粘" */
/* 另外:父元素不能有 overflow: hidden,否则 sticky 失效 */

但 sticky 有几个要注意:

5. z-index 层级控制

定位元素会"叠"在一起,z-index 控制谁在上谁在下。值越大越靠上。

.overlay { z-index: 1000; }   /* 弹窗最上层 */
.header  { z-index: 100; }    /* 吸顶导航次之 */
.dropdown { z-index: 50; }    /* 下拉菜单 */
.card    { z-index: 1; }      /* 普通卡片 */

/* 注意:
   1. z-index 只对 position 非 static 的元素生效
   2. 同层级比 z-index 大的覆盖小的
   3. 不同层级的"堆叠上下文"互相独立,z-index 不直接比较
   4. 滥用 z-index 容易陷入"军备竞赛",能用文档流就别用定位 */

关于 z-index 有几个关键认知:

6. top/right/bottom/left 与 inset 简写

四个方向偏移量,和 margin 简写规则类似(上、右、下、左)。新的 inset 属性可以一次性设四个方向。

7. 何时该用定位

小结

定位是处理"叠层"和"脱离文档流"需求的工具。掌握五种取值:static 默认、relative 不脱流、absolute 脱流(父 relative 子 absolute)、fixed 视窗固定、sticky 滚动吸顶;z-index 控制层级但要慎用。下一篇讲过渡与动画——让页面真正"动"起来。

← 上一篇 CSS Grid 网格布局

下一篇 CSS 过渡与动画

✈️💬