引入
在页面布局中,元素的位置往往决定了用户体验的好坏。CSS提供了 position 属性来控制元素在页面上的精确位置。这篇文章会从最基础的文档流讲起,带你彻底搞懂相对定位,绝对定位,固定定位,粘性定位 以及层叠上下文 z-index。
无论你是刚刚入门的前端小白,还是想巩固基础的进阶选手,相信读完都会有所收获。
文档流
浏览器在渲染 HTML 页面时,默认顺序是从上到下,从左到右把元素一个个摆放到页面上。这种默认的排列方式就叫做文档流(Normal Flow)。
1. 块级元素(Block)
-
例如:
<div>,<h1>,<p>,<section> -
默认独占父容器的一整行,前后元素会换行
-
可以设置宽高
-
默认宽度为父容器宽度的100%
<div style="background: lightblue; width: 200px; height: 50px;">块级元素</div>
<div style="background: lightgreen;">我也会独占一行</div>
行内元素(inline)
- 例如:
<span>、<a>、<strong>、<em> - 可以在一行内水平排列,直到宽度不够 才换行
- 不能设置宽高,大小由内容撑开
- 只能设置左右 margin / padding ,上下margin 不生效
<span style="background: pink;">我是行内元素</span>
<span style="background: orange;">我会在同行</span>
<a href="#">链接也是行内</a>
3. 行内块级元素(Inline-Block)
- 例如:
<input>,<button>,<img>,<select> - 兼具两者优点:可以同行排列,同时能设置宽高
- 通过 dispaly:inline-block 可以把块级元素变成行内块级元素
<input style="width: 100px; height: 30px;" placeholder="输入框">
<button style="width: 80px; height: 40px;">按钮</button>
display 属性可以自由改变元素的类型,比如 display:block,display:inline,display:inline-block。
二. 为什么要用定位?
文档流是'自动排版',但实际开发中经常需要让某个元素脱离默认排列,比如:
- 一个弹窗浮动在页面上方
- 带小红标的头像(消息提醒的角标)
- 固定不动的返回顶部按钮
- 滚动时吸顶的导航栏
这就需要用到 position 定位属性。
三. 定位布局的实现
position 有四个常用值:relative,absolute,fixed,sticky.它们配合 top,right,bottom,left来移动元素。
1.相对定位-position:relative
参考对象:元素自身在文档流中的原始位置
是否脱离文档流:否 (原来的空间依然占位)
.box {
position: relative;
top: 20px; /* 相对于原位置向下移 20px */
left: 10px; /* 向右移 10px */
}
特点:
- 移动后,其他元素不会填补它原来的空白。
- 经常作为 绝对定位元素的参考容器(子绝父相)
常见场景:微调图标位置,制作“子绝父相”中的父级
2. 绝对定位- posistion:absolute
参考对象:带定位属性的父级元素(即带relative/absolute/fixed/sticky),找不到继续往上找直到找到body为止
是否脱离文档流:是,原有空间被其他元素顶替
.parent {
position: relative; /* 成为子元素的参考 */
}
.child {
position: absolute;
top: 0;
right: 0; /* 相对于父容器右上角 */
}
注意:
- 以拥有定位属性的父容器为参考标准,如果没有就层层往上找拥有定位属性的父容器,直到找到 body 为止
- 百分比 top /left 是相对参考元素的宽高计算的
常见场景:弹窗 ,下拉菜单,自定义提示框,头像角标。
<div style="position: relative; width: 200px; height: 200px; background: #eee;">
<span style="position: absolute; bottom: 5px; right: 5px;">📌</span>
</div>
3. 固定定位- position:fixed
参考对象:浏览器可视窗口
是否脱离文档流: 是
.fixed-btn {
position: fixed;
bottom: 30px;
right: 20px;
}
特点:
- 滚动页面时位置不变,始终在视窗的固定位置
- 不随父元素滚动,但注意父元素设置transform会破坏固定定位(强行变成相对于该父元素)
常见场景:回到顶部按钮,浮动客服,固定导航栏。
粘性定位- position:sticky
参考对象:屏幕 是否脱离文档流: 达到阈值前不脱离,达到阈值后会和fixed一样
.sticky-nav {
position: sticky;
top: 0; /* 必须设置阈值,否则不生效 */
}
注意:
- 必须设置 top/bottom等阈值
- 父容器高度必须大于粘性元素的高度
常见场景:吸顶导航,表格表头固定,分类标题。
层级: z-index
-
层级要生效,必须要配合定位属性
-
只能在兄弟元素之间相比较(一般是产生堆叠的时候)