一篇文章搞懂CSS中的定位布局

36 阅读4分钟

引入

在页面布局中,元素的位置往往决定了用户体验的好坏。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

  1. 层级要生效,必须要配合定位属性

  2. 只能在兄弟元素之间相比较(一般是产生堆叠的时候)