CSS 定位(Position)
适用人群:前端基础薄弱、目标用 T3 Stack 写生产项目的开发者 学完收获:搞定所有精确定位 UI 场景,不再出现元素乱跑、父容器塌陷、层级错乱问题
一、前置基础概念
1. 什么是文档流?
浏览器默认的排版规则,相当于排队规则:
- 块级元素从上到下依次排列,每个占整行
- 行内元素从左到右依次排列,排满换行
- 每个元素默认占自己的位置,互不重叠
2. 什么是脱离文档流?
元素不遵守默认排队规则,相当于从队伍里跑出去:
- 其他排队元素会补位/无视它的存在
- 常用的
float、position: absolute/fixed都会触发脱离文档流
| 脱离方式 | 脱离程度 | 表现 |
|---|---|---|
| float | 部分脱离 | 后面的块元素会补位,但文字会环绕浮动元素 |
| absolute/fixed | 完全脱离 | 其他元素完全无视它的存在,不会补位 |
二、5 种定位方式全解(含 Tailwind 对应写法)
定位核心作用:给元素装 GPS,精准放到页面任意位置。
1. static(默认定位)
- 定义:不开启定位,元素遵守默认文档流规则
- 参考对象:无
- 特点:
top/left/right/bottom/z-index全部不生效 - Tailwind 写法:
static(默认不用写) - 用途:重置其他定位样式
2. relative(相对定位)
- 定义:相对于自己原来的文档流位置偏移
- 参考对象:自己原本的位置
- 特点:不会脱离文档流,原位置还占着,只是视觉偏移
- Tailwind 写法:
relative+top-2/left-10/-bottom-1 - 核心用途:
- 微调元素位置
- 给子元素的
absolute当参考容器(最常用)
{
/* 相对于原位置向右偏移10px,向下偏移5px */
}
<div className="relative top-5 left-10 bg-blue-100 p-4">相对定位元素</div>;
3. absolute(绝对定位)
- 定义:相对于最近的「非 static 定位的祖先元素」偏移
- 参考对象:最近的有
relative/absolute/fixed/sticky的父元素,如果没有就相对于整个页面 - 特点:完全脱离文档流,不占原位置,其他元素无视它
- Tailwind 写法:
absolute+top-0/right-10/bottom-1/left-1/2 - 核心用途:弹窗、徽标、下拉菜单、图标重叠等需要精确定位的场景
{
/* 父元素加relative当参考 */
}
<div className="relative h-40 w-40 bg-gray-100">
{/* 子元素相对于父元素放在右下角 */}
<span className="absolute right-2 bottom-2 rounded bg-green-500 px-2 py-1 text-white">
绝对定位
</span>
</div>;
4. fixed(固定定位)
- 定义:相对于浏览器可视窗口偏移
- 参考对象:浏览器窗口,滚动页面也不会动
- 特点:完全脱离文档流
- Tailwind 写法:
fixed+top-0/right-5/bottom-5 - 核心用途:固定导航栏、回到顶部按钮、悬浮客服、全局弹窗
{
/* 固定在页面右下角的回到顶部按钮 */
}
<button className="fixed right-5 bottom-5 flex h-10 w-10 items-center justify-center rounded-full bg-blue-500 text-white">
↑
</button>;
5. sticky(粘性定位)
- 定义:滚动到指定阈值前是正常文档流,到阈值后变成 fixed 固定
- 参考对象:最近的可滚动父元素
- 特点:不脱离文档流,必须指定
top/left/right/bottom阈值才生效 - Tailwind 写法:
sticky+top-0 - 核心用途:表格表头、分类标题、粘性侧边栏
<div className="h-[200px] overflow-y-auto border">
<div className="h-10 bg-gray-100">顶部内容</div>
{/* 滚动到顶部就固定住 */}
<div className="sticky top-0 bg-orange-500 p-2 text-white">
粘性标题,滚动到顶部就停住
</div>
<div className="h-[300px] p-2">大量内容...</div>
</div>
三、核心组合:relative + absolute 黄金搭档
90% 的定位场景都是这个组合:
- 父元素加
relative:作为子元素的定位参考,自己不脱离文档流,正常占位置 - 子元素加
absolute:相对于父元素精准偏移,不会跑到父元素外面去
{
/* T3项目里常用的消息徽标 */
}
<button className="relative rounded bg-gray-100 p-2">
消息中心
{/* 红色小圆点徽标,相对于按钮放在右上角 */}
<span className="absolute -top-1 -right-1 flex h-4 w-4 items-center justify-center rounded-full bg-red-500 text-xs text-white">
3
</span>
</button>;
四、易混淆区分:定位 vs 浮动
| 维度 | 浮动(float) | 定位(position) |
|---|---|---|
| 移动方向 | 只能左/右 | 上下左右任意位置 |
| 参考对象 | 父元素边界 | 自己/祖先元素/浏览器窗口 |
| 用途 | 文字绕排、老旧布局(已被 Flex 取代) | 精确定位、悬浮元素 |
| 脱离程度 | 部分脱离 | 部分/完全脱离 |
T3 项目开发准则:布局用 Flex/Grid,精确定位才用 position,完全不用 float 做布局。
五、高频踩坑避坑指南
1. absolute 父元素高度塌陷
问题:子元素用 absolute 完全脱离文档流,父元素没有内容撑开,高度变成 0
解决:给父元素加 min-h-[xx] 指定最小高度,或者加 padding 预留位置
2. z-index 不生效
问题:设置了 z-index 但是层级还是不对 原因:只有非 static 定位的元素 z-index 才生效,层级是相对于父级的堆叠上下文 解决:给需要调整层级的元素加定位(relative 即可),不要乱加超大 z-index,统一管控全局层级:
| 层级用途 | 推荐值 |
|---|---|
| 普通悬浮元素 | z-10 |
| 下拉菜单 | z-30 |
| 固定导航 | z-40 |
| 全局弹窗 | z-50 |
3. sticky 不生效
常见原因:
- 没有指定
top/left等阈值 - 父元素设置了
overflow: hidden - 父元素高度和 sticky 元素一样高,没有滚动空间
六、T3 项目实战常用代码片段
1. 固定顶部导航栏
<nav className="fixed top-0 right-0 left-0 z-40 flex h-16 items-center bg-white px-4 shadow-sm">
导航栏内容
</nav>;
{
/* 给下面的内容加padding,避免被导航栏挡住 */
}
<main className="pt-16">页面内容</main>;
2. 居中弹窗
{
/* 遮罩层 */
}
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
{/* 弹窗内容 */}
<div className="w-[400px] rounded-lg bg-white p-6">弹窗内容</div>
</div>;
3. 粘性侧边栏
<div className="flex gap-4">
<aside className="sticky top-16 h-fit w-64">
侧边栏,滚动时固定在顶部16px位置
</aside>
<main className="flex-1">主内容</main>
</div>
七、速查表
| 定位类型 | CSS 写法 | Tailwind 写法 | 参考对象 | 常用场景 |
|---|---|---|---|---|
| 默认 | position: static | static | 无 | 重置定位 |
| 相对 | position: relative | relative | 自己原位置 | 做 absolute 参考容器 |
| 绝对 | position: absolute | absolute | 最近非 static 父元素 | 徽标、下拉菜单 |
| 固定 | position: fixed | fixed | 浏览器窗口 | 固定导航、弹窗 |
| 粘性 | position: sticky | sticky | 滚动父元素 | 表头、粘性侧边栏 |