CSS position 定位布局:从入门到踩坑,一篇全搞懂

8 阅读10分钟

五种定位 + z-index 层级 + 实战场景 + 新手常见坑,新手向超详细完整版

图片.png

前言

学 CSS 布局的时候,以为布局很简单,结果一做项目就发现:弹窗怎么居中?导航栏怎么吸顶?侧边栏怎么悬浮?图标怎么精准放到文字旁边?

全都需要 position 定位。

可五种定位值各有各的规矩,relativeabsolute 的区别、fixedsticky 什么时候用、z-index 为什么有时候不生效……踩了一堆坑才慢慢理清楚。

这篇文章把定位布局的所有知识点、代码示例、实战场景、新手常踩的坑,一次性讲透。


一、定位布局是干什么的?

一句话:自由控制元素在页面上的精准位置。

标准文档流里,元素从上到下、从左到右老老实实排队。但有些效果文档流做不到:

  • 悬浮客服按钮
  • 固定顶部导航栏
  • 弹窗遮罩层
  • 侧边目录
  • 吸顶表头

这些都需要用 position 让元素"跳出队列",放到你想要的位置。

⚠️ 重要:不是所有定位都脱离文档流!

定位值是否脱离文档流
static❌ 不脱离,正常排队
relative❌ 不脱离,原位置占位
absolute✅ 完全脱离,不占位
fixed✅ 完全脱离,不占位
sticky❌ 不脱离(滚动时表现为 fixed,但仍占位)

基本语法

.box {
    position: 定位值;    /* static / relative / absolute / fixed / sticky */
    top: 10px;           /* 向下偏移 10px */
    left: 20px;          /* 向右偏移 20px */
    /* right / bottom 同理 */
}

二、五种定位值详解

1. static 静态定位(默认值)

所有元素默认就是 static,不写 position 和写了 position: static 效果完全一样。

特点

  • 不脱离文档流,老老实实排队
  • topleftrightbottom 全部无效
  • z-index 也无效

用途:唯一用途就是取消其他定位,恢复默认

/* 默认状态,什么都不做 */
.box {
    position: static;
    top: 100px;  /* ❌ 无效,不会偏移 */
}
/* 实际用途:取消定位 */
.box {
    position: absolute;
    /* 一堆定位操作... */
}

/* 某个场景下想恢复默认 */
.box {
    position: static;  /* ✅ 取消定位,回到文档流 */
}

2. relative 相对定位

核心特点:不脱离文档流,相对于自身原始位置偏移。

什么叫"偏自身"?你坐在教室座位上,身体往前挪一点,但座位依旧是你的,别人坐不了。

请注意:相对定位的占坑大小不变,偏移出去的区域不属于它的占位,也不挤占别人空间

四大必记特点

特点说明
不脱离文档流原位置继续占位,旁边元素不会挤过来
参照物是自身以没定位之前的位置为基准偏移,和父盒子无关
不影响其他元素自己挪位置,别人不动
z-index 生效可以设置层级盖住其他元素

偏移方向易错点

属性正数方向负数方向
top⬇️ 向下⬆️ 向上
left➡️ 向右⬅️ 向左
bottom⬆️ 向上⬇️ 向下
right⬅️ 向左➡️ 向右
/* 基础用法:微调位置 */
.box {
    position: relative;
    left: 30px;  /* 从自己原来位置,向右移 30px */
    top: 20px;   /* 从自己原来位置,向下移 20px */
}
/* 最常用场景:给绝对定位当父级参照物(子绝父相) */
.parent {
    position: relative;  /* 只当参照物,不偏移 */
    width: 500px;
    height: 500px;
}

.child {
    position: absolute;  /* 子元素相对父元素定位 */
    top: 10px;
    right: 10px;
}
/* 实际场景:图标和文字对齐微调 */
.icon-text {
    position: relative;
    top: 2px;  /* 图标偏上,往下挪 2px 和文字对齐 */
}

新手最容易踩的 5 个坑

  1. 用 relative 做页面整体布局 → ❌ 大忌!占位还在,容易出现大片空白
  2. 以为 relative 能居中 → ❌ 居中优先用 flex / grid
  3. 多个 relative 互相堆叠 → ❌ 极易重叠错乱
  4. left 设过大 → ❌ 超出可视区,出现横向滚动条
  5. 用 relative 做悬浮栏 → ❌ 滚动时跟着页面走,做不了悬浮

relative 和不写 position 相比,获得了移动的能力,常用于div 盒子中的各种标签,未读标签的小红点等等...


3. absolute 绝对定位(重点)

核心特点:完全脱离文档流,不占位置,找最近的已定位祖先做参照物。

三大必记特点

特点说明
完全脱离文档流不占位置,其他元素当它不存在
参照物是最近的已定位祖先父元素有定位(非 static)→ 相对父元素;父无定位 → 相对浏览器视口
最常用搭配:子绝父相relative + 子 absolute
/* 经典场景:父相子绝,子元素放到父元素右上角 */
.father {
    position: relative;
    width: 300px;
    height: 300px;
    background: #f0f0f0;
}

.son {
    position: absolute;
    top: 0;
    right: 0;
    background: red;
    color: white;
    padding: 4px 8px;
}
/* 经典场景:水平垂直居中 */
.father {
    position: relative;
    width: 500px;
    height: 500px;
}

.son {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);  /* 往回挪自身宽高的一半 */
}
/* 实际场景:商品卡片上的角标 */
.card {
    position: relative;
    width: 200px;
    height: 250px;
}

.badge {
    position: absolute;
    top: -10px;
    left: -10px;
    background: red;
    color: white;
    border-radius: 50%;
    width: 40px;
    height: 40px;
}

⚠️ 注意:绝对定位元素不占位,会覆盖其他元素。如果不想覆盖,需要手动设置 z-index 或给父容器留出空间。


4. fixed 固定定位

核心特点:脱离文档流,参照物永远是浏览器视口,页面滚动也纹丝不动。

三大必记特点

特点说明
脱离文档流不占位置
参照物是浏览器窗口不是父元素,不是页面,是屏幕
滚动不动页面怎么滚,它都在原地
/* 经典场景:固定顶部导航栏 */
.nav {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 60px;
    background: white;
    box-shadow: 0 2px 8px rgba(0,0,0,0.1);
    z-index: 999;
}
/* 经典场景:右下角回到顶部按钮 */
.back-top {
    position: fixed;
    right: 20px;
    bottom: 30px;
    width: 44px;
    height: 44px;
    background: #409eff;
    color: white;
    border-radius: 50%;
}
/* 经典场景:右侧悬浮客服 */
.customer-service {
    position: fixed;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
}

⚠️ 注意:使用 fixed 时,页面其他内容会被它覆盖,记得给 body 或主内容区加 padding-top(固定导航栏)或 margin-right(侧边栏)留出空间。


5. sticky 粘性定位

核心特点:混合了 relativefixed 的行为,滚动到阈值时"吸住"。

工作原理

  1. 滚动前:表现为 relative,正常占位
  2. 滚动到阈值(top 指定的值):切换为 fixed,吸住不动
  3. 滚出父容器范围:恢复 relative,跟着页面走
/* 经典场景:导航吸顶 */
.sticky-nav {
    position: sticky;
    top: 0;  /* 距离顶部 0px 时吸顶 */
    background: white;
    z-index: 100;
}
/* 实际场景:表格表头固定 */
.table-container {
    height: 400px;
    overflow-y: auto;
}

.table-header {
    position: sticky;
    top: 0;
    background: #fafafa;
}
/* 实际场景:侧边目录高亮跟随 */
.sidebar {
    position: sticky;
    top: 80px;  /* 距离顶部 80px 时吸住(留出导航栏高度) */
}

⚠️ 注意

  • sticky 必须指定 top / left 等阈值,否则不会生效
  • 只在父容器范围内生效,滚出父级就失效
  • 父容器不能有 overflow: hidden,否则 sticky 会失效

三、relative vs fixed 做侧边栏,到底有什么区别?

这个问题我一开始也搞混了,两种定位都能做出侧边栏的样子,但行为完全不同。

核心区别

对比项relative 侧边栏fixed 侧边栏
参照物自身原始位置浏览器视口
是否占位✅ 占位,原位置留空❌ 不占位,脱离文档流
滚动行为跟着页面一起滚走永远钉在屏幕上
适用场景跟着内容走的侧边栏常驻悬浮侧边栏
/* relative 侧边栏:随页面滚动 */
.side-relative {
    position: relative;
    left: 0;
    top: 100px;
    width: 200px;
}
/* 页面往下滚 → 侧边栏跟着消失 */
/* fixed 侧边栏:永久悬浮 */
.side-fixed {
    position: fixed;
    right: 20px;
    top: 150px;
    width: 200px;
}
/* 页面怎么滚 → 侧边栏始终在屏幕右侧 */

一句话总结:同样能做出侧边栏外观,relative 依附文档流跟随页面流动,fixed 依附浏览器窗口永久悬浮。开发中悬浮控件一律用 fixed,局部微调位置用 relative

如果你要做一个"文章目录",希望滚动时目录始终可见,我会用 fixed,它不占位,脱离文档流,能实现常驻。


四、定位层级 z-index

z-index 控制定位元素的堆叠顺序,数值越大越靠上。

核心规则

规则说明
只对定位元素生效position: static 的元素设置 z-index 无效
数值越大层级越高支持正负整数,默认 z-index: auto
同级定位后写在上没有 z-index 时,后面的元素盖住前面的
只影响同级元素不会跨父元素比较
/* 基础用法 */
.box1 {
    position: absolute;
    z-index: 1;  /* 在下层 */
}

.box2 {
    position: absolute;
    z-index: 10; /* 在上层,盖住 box1 */
}
/* 实际场景:弹窗遮罩层 */
.overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.5);
    z-index: 1000;  /* 遮罩层 */
}

.modal {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 1001;  /* 弹窗在遮罩层上面 */
}
/* ⚠️ z-index 不生效的常见原因 */
.parent {
    position: relative;
    z-index: 1;  /* 父元素创建了层叠上下文 */
}

/* 子元素 z-index 再高,也不会超过另一个 z-index 更高的父元素的子元素 */
.child {
    position: absolute;
    z-index: 9999;  /* 仍然受限于父元素的层叠上下文 */
}

⚠️ z-index 不生效的常见原因

  1. 元素没有设置 position(或设为 static
  2. 父元素创建了新的层叠上下文(设置了 transformopacityfilter 等)
  3. 同一父元素内的子元素,z-index 只在同级之间比较

五、五种定位速记口诀

定位占位参照物滚动行为一句话
static正常默认无效果,取消定位用
relative自身跟着走留空位,偏自身,做父级
absolute已定位父级跟着走不占位,找父级,自由放
fixed浏览器视口不动不占位,盯窗口,做悬浮
sticky✅→❌视口(阈值内)吸住滚动切换,区间吸顶

六、实战场景速查表

场景推荐定位代码要点
元素微调位置relativetop / left 小幅偏移
盒子内部放小图标relative + 子 absolute子绝父相
弹窗 + 遮罩层fixed + z-index遮罩 1000,弹窗 1001
全局固定导航栏fixed + top: 0记得给 body 加 padding-top
滚动吸顶导航sticky + top: 0父容器不能有 overflow: hidden
水平垂直居中absolute + transformtop: 50%; left: 50%; translate(-50%, -50%)
商品卡片角标relative + 子 absolutetop: -10px; left: -10px
右下角回到顶部fixed + right/bottomright: 20px; bottom: 30px

总结

CSS 定位是页面布局的灵魂属性。浮动适合横向排列,Flex 适合一维弹性布局,Grid 适合二维排版,而定位布局主打精准控位,是实现网页特殊视觉效果、交互悬浮效果必不可少的核心技术。

不用死记硬背五种定位的所有细节,记住核心区别就够了:

  • relative:占位置,偏自身,专做父级与微调
  • absolute:不占位,找父级,自由摆放
  • fixed:不占位,盯窗口,做悬浮
  • sticky:滚动切换,区间吸顶
  • static:默认无效果

日常开发中,90% 的场景都是"子绝父相"和 fixed 悬浮,把这两个用熟,定位布局就算入门了。

CSS里面的学问很深,有时定位出bug,很有可能是你某个知识点没有掌握,但是一步一个脚印,其实CSS也不难

路漫漫其修远兮,吾将上下而求索


💡 建议补充:可以配一张思维导图,把五种定位的关系和区别可视化