写页面时经常遇到这些需求:小角标要贴在卡片右上角、导航栏要固定在页面顶部、弹窗要盖在屏幕正中间。这些都靠 position 实现。这篇讲清楚 static、relative、absolute、fixed 四种定位方式的区别,以及最常用的搭配套路。
static:默认值,先从它说起
每个元素默认都是 static,也就是按文档流从上往下排,谁也不特殊。static 元素设置 top、left 这些偏移属性是完全无效的——想让元素挪位置,第一步先把 position 换掉。
relative:相对自己原来的位置挪
.tip {
position: relative;
top: 10px; /* 向下挪 10px */
left: 20px; /* 向右挪 20px */
}
两个要点:top 是「往下挪」,想往上要写负值;元素挪走了,原来占的位置还留着,后面的元素不会补上来。
relative 更重要的角色是当定位参照物——下一节的 absolute 就靠它。
absolute:相对最近的定位祖先
absolute 让元素脱离文档流,相对「最近的非 static 祖先」定位。最经典的场景是角标:
<div class="card">
<span class="badge">新</span>
</div>
.card {
position: relative; /* 给子元素当参照物 */
width: 200px;
height: 100px;
}
.badge {
position: absolute;
top: 8px;
right: 8px; /* 贴在卡片右上角 */
}
注意父级一定要加 position: relative,这招俗称「子绝父相」。如果父级全都没有定位,absolute 元素会一直往外层找,最后相对整个页面定位——角标飞到天边去,多半就是这个原因。
fixed:相对浏览器窗口,滚动也不动
.navbar {
position: fixed;
top: 0;
left: 0;
right: 0; /* 左右拉满 */
height: 50px;
}
fixed 同样脱离文档流,后面的内容会顶到导航栏底下,记得给 body 加个 padding-top: 50px 补偿空缺。
组合技:绝对定位居中
弹窗居中是定位最经典的用法:
.dialog {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
先把元素的左上角放到屏幕正中,再往回挪自己宽高的一半,弹窗无论多大都精确居中。
另外,absolute 和 fixed 元素重叠时,默认是写在后面的盖住写在前面;想手动控制层级,就给元素加 z-index,数值大的在上层:
.dialog { z-index: 100; } /* 弹窗盖住普通角标 */
小结
- static 是默认值,设置偏移无效
- relative 相对自身偏移、原位置仍占位,主要用来当参照物
- absolute 相对最近的定位祖先,「子绝父相」是最常见搭配
- fixed 相对浏览器窗口,滚动不动,记得补偿文档流空缺
- top/left 的参照物是定位祖先而不是浏览器,位置不对先查参照物
把这篇和之前的 Flexbox、Grid 放在一起用,常见的布局需求基本都能拿下了。
子绝父相这口诀可以,之前角标到处乱飞,就是因为父级忘了加 relative,看完秒懂。