Appearance
✨ 定位 👌
视觉格式化模型(布局规则)大体上将页面中盒子的排列分为三种方式:
- 常规流
- 浮动:
float - 定位:
position
定位用于手动控制元素在包含块中的精准位置,常用于悬浮按钮、弹层、提示气泡、固定导航等场景。
1. 基本概念
position决定元素是否参与常规文档流以及如何计算偏移。- 只要
position不是static,该元素被视为“定位元素”。除relative外,其余定位都会脱离文档流。 - 脱离文档流的元素:
- 常规流元素的排列会忽略它。
- 常规流容器的自动高度不会包含它。
TIP
定位是精确摆放的利器,但并非通用布局方案。优先考虑 Flex/Grid,定位用于局部微调或悬浮/覆盖类效果。
2. position 属性与取值
static(默认):静态定位,不脱离文档流,偏移属性无效。relative:相对定位,不脱离文档流,允许使用top/right/bottom/left在“原位置”基础上偏移。absolute:绝对定位,脱离文档流,偏移相对于“包含块”计算(见下文)。宽高为auto时适应内容。fixed:固定定位,通常相对于视口(浏览器可视区域)固定位置,常用于固定头部/悬浮按钮。sticky:粘性定位,介于relative和fixed之间;在滚动到阈值前表现为相对定位,达到阈值后“吸附”在指定位置。
TIP
sticky 常用于吸顶导航:在接近顶部时吸附停靠,离开区域后恢复原位。
3. 包含块(containing block)与偏移
偏移属性 top/right/bottom/left 表示元素与“包含块”的距离。
- 绝对定位(
absolute):- 查找祖先中“第一个定位元素”(
position非static)。该祖先的填充盒(padding box)作为包含块。 - 若未找到,则包含块为初始包含块(通常是页面根元素区域)。
- 查找祖先中“第一个定位元素”(
- 固定定位(
fixed):- 一般以视口作为包含块。
- 某些情况下(如祖先有
transform/filter等创建新的包含块)会改为该祖先。
- 相对/粘性定位:
- 相对定位以自身原始位置为参考进行偏移;
- 粘性定位以其最近的可滚动祖先和阈值为参考(如
top: 0)。
偏移规则要点:
- 同时设置水平(
left与right)或垂直(top与bottom)两侧偏移且元素定宽/定高时,会在剩余空间中按约束进行分配。 - 仅设置一个方向更直观;需要“拉伸”时才考虑两侧同时设置。
4. 相对定位(relative)
特点:
- 不脱离文档流(原位置仍占位)。
- 通过偏移属性在原位置基础上“挪动”,不会影响其他元素的排布。
- 常用于细微位置微调、为绝对定位子元素提供参考上下文。
html
<!-- 相对定位:微调位置 -->
<div class="card">
<span class="badge">NEW</span>
</div>css
.card {
position: relative; /* 为内部绝对定位提供参考 */
width: 240px;
height: 120px;
background: #f5f5f5;
}
.badge {
position: relative; /* 相对定位,轻微上移右移 */
top: -6px;
left: 8px;
background: #ff6b6b;
color: #fff;
padding: 2px 6px;
border-radius: 4px;
}5. 绝对定位(absolute)
特点:
- 脱离文档流,不再占据原来的空间。
- 默认宽高为
auto,随内容收缩。 - 偏移相对于“最近的定位祖先”的填充盒(无则相对于页面初始包含块)。
- 常用于图标角标、气泡层、弹窗内元素的精确覆盖。
html
<!-- 绝对定位:角标与覆盖层 -->
<div class="card">
<img class="cover" src="https://picsum.photos/240/120" alt="cover" />
<span class="corner">HOT</span>
</div>css
.card {
position: relative; /* 提供包含块 */
width: 240px;
height: 120px;
}
.cover {
width: 100%;
height: 100%;
object-fit: cover;
}
.corner {
position: absolute;
right: 8px;
top: 8px;
background: #ff6b6b;
color: #fff;
padding: 2px 6px;
border-radius: 4px;
}TIP
绝对定位的子元素不会撑开父元素高度。若父元素需要包含它们的高度,需显式设置父元素尺寸或通过其他布局方案实现。
6. 固定定位(fixed)
特点:
- 脱离文档流,固定在视口指定位置(除非受祖先创建的包含块影响)。
- 常用于固定头部、返回顶部按钮、浮动工具条。
html
<!-- 固定定位:返回顶部按钮 -->
<button class="back-top">↑ TOP</button>css
.back-top {
position: fixed;
right: 16px;
bottom: 16px;
padding: 8px 12px;
background: #008c8c;
color: #fff;
border: none;
border-radius: 6px;
cursor: pointer;
}TIP
移动端某些浏览器对 fixed 支持有差异;当祖先元素使用了 transform/filter 等属性时,固定元素可能会相对该祖先定位而非视口。
7. 粘性定位(sticky)
特点:
- 初始表现为相对定位,滚动到阈值后“吸附”在指定位置。
- 常用于吸顶导航、分组标题吸附。
html
<!-- 粘性定位:吸顶导航 -->
<nav class="nav">导航</nav>
<section class="content">长内容……</section>css
.nav {
position: sticky;
top: 0; /* 到达视口顶部时吸附 */
background: #fff;
border-bottom: 1px solid #eee;
z-index: 10; /* 防止被内容覆盖 */
}
.content {
height: 1500px;
}8. 定位下的居中
- 水平或垂直方向居中(适用于
absolute/fixed):- 定宽(或定高);
- 将左右(或上下)距离设置为
0; - 将对应方向的
margin设为auto,自动吸收剩余空间。
html
<!-- 绝对定位:水平居中 -->
<div class="wrap">
<div class="modal">对话框</div>
</div>css
.wrap {
position: relative;
height: 240px;
background: #f5f5f5;
}
.modal {
position: absolute;
width: 160px;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto; /* 水平居中 */
top: 24px;
background: #fff;
border: 1px solid #ddd;
padding: 12px;
border-radius: 8px;
}- 完全居中(更常用):
css
.center {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%); /* 不依赖定宽高 */
}9. 多个定位元素重叠与层级
- 层叠上下文:决定元素重叠顺序的规则集合。
z-index控制层级,数值越大,元素越靠上;可以为负数(可能被常规流/浮动元素覆盖)。- 一般只有设置了
position的元素使用z-index才有效;z-index会创建新的层叠上下文。
css
.banner {
position: relative;
}
.mask {
position: absolute;
inset: 0;
background: rgba(0, 0, 0, 0.3);
z-index: 1;
}
.title {
position: relative;
z-index: 2;
}TIP
有些属性也会创建层叠上下文(如 opacity < 1、transform、filter 等)。当层级表现异常时,检查是否无意间创建了新的上下文。
10. 常见问题与最佳实践
- 不要用绝对定位做通用布局:优先 Flex/Grid;绝对定位更适合覆盖/标注类元素。
- 绝对/固定定位子元素不撑开父元素:若需要父容器自适应高度,请改用常规流或显式设置尺寸。
- 合理设置包含块:需要相对父容器定位时,将父容器设为
position: relative。 - 注意移动端固定定位兼容性:必要时用
sticky替代,或避免祖先使用transform。 - 控制层级:仅在必要时设置
z-index,避免无序递增导致层级混乱。
11. 综合示例:角标与居中弹窗
html
<div class="card">
<img class="cover" src="https://picsum.photos/320/180" alt="cover" />
<span class="tag">SALE</span>
<div class="dialog">Hello</div>
</div>css
.card {
position: relative;
width: 320px;
height: 180px;
}
.cover {
width: 100%;
height: 100%;
object-fit: cover;
}
.tag {
position: absolute;
left: 8px;
top: 8px;
background: #ff6b6b;
color: #fff;
padding: 2px 6px;
border-radius: 4px;
}
.dialog {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background: #fff;
padding: 12px;
border-radius: 8px;
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.12);
}12. 小结
relative:不脱流,微调位置/作为包含块参照。absolute:脱流,相对最近定位祖先的填充盒偏移。fixed:脱流,相对视口固定位置(可能受祖先影响)。sticky:相对与固定的结合,适合吸顶/吸底场景。- 偏移围绕“包含块”计算;居中常用
translate(-50%, -50%)技巧。
以上内容与常规流、浮动互补,形成完整的布局与叠加策略。
