CSS 定位(position)是一种用于精确控制元素在页面上位置的机制。通过设置position属性,可以将元素放置在页面的特定位置,而不仅仅依赖于正常的文档流布局。使用定位可以实现更复杂和灵活的页面布局效果,因此这是前端 CSS 样式学习必须掌握的。本文会介绍有关的四种 CSS 定位方式,并从它们各自的常用场景出发讲解其实现方式。
相对定位
相对定位常用于微调元素的位置,同时不影响周围元素的布局。因为它在文档流中仍然保留其原始位置,只是视觉上发生了偏移。
如下 HTML 结构中,有一个外层.outer包裹两个块元素:
<div class="outer">
<div class="d d1">D1</div>
<div class="d d2">D2</div>
</div>
给这些元素添加样式作区分:
.outer {
width: 200px;
background-color: gray;
padding: 10px;
}
.d {
width: 100px;
height: 100px;
}
.d1 {
background-color: orange;
}
.d2 {
background-color: lightblue;
}
页面中的展示如下:
给.d1开启相对定位position: relative,并相对于左边偏移left: 50px:
.d1 {
background-color: orange;
position: relative;
left: 50px;
}
此时页面的变化如下:
不过需要注意如果继续偏移,则可能会超出父元素:
.d1 {
background-color: orange;
position: relative;
left: 150px;
}
如果反向偏移,则又会超出浏览器:
.d1 {
background-color: orange;
position: relative;
left: -50px;
}
另外,相对定位可以与浮动共存,尝试让.d1浮动到右边:
.d1 {
background-color: orange;
position: relative;
float: right;
}
页面中呈现的效果:
来总结一下相对定位的特点:
- 相对定位不会让元素脱离文档流。
- 相对定位是相对于元素在正常文档流中的原始位置进行定位的。
- 相对定位可以与浮动共存,但此刻元素又是脱离文档流的。
绝对定位
如下 HTML 结构中,有一个外层.outer包裹两个块元素:
<div class="outer">
<div class="d d1">D1</div>
<div class="d d2">D2</div>
</div>
给这些元素添加样式作区分:
.outer {
width: 200px;
background-color: gray;
padding: 10px;
}
.d {
width: 100px;
height: 100px;
}
.d1 {
background-color: orange;
}
.d2 {
background-color: lightblue;
}
给.d1开启绝对定位position: absolute:
.d1 {
background-color: orange;
position: absolute;
}
分析一下绝对定位后的效果:
- 开启绝对定位后,
.d1脱离了文档流,并完全地覆盖在.d2上面。 - 与浮动稍有区别,文字不会有环绕效果,
.d2中的文字并没有 “流动” 在周围。
继续尝试给.d1一个偏移left: 0:
.d1 {
background-color: orange;
position: absolute;
left: 0
}
会发现.d1在这里实际上是相对于浏览器<html>定位:
但是如果给其父元素开启一个定位(position: relative),则又是相对于父元素定位:
来总结一下绝对定位的特点:
- 绝对定位的定位相对于其
包含块,如果父元素及祖先元素开启定位(相对、绝对)那么就是包含块,如果都没有,就相对于根元素这个包含块。 - 绝对定位的元素是
定位元素,具有inline-block的特性,比如把<span>作为绝对元素那么就具有宽高。 - 绝对定位是脱离文档流的。
- 绝对定位不可以与浮动共存。
固定定位
固定定位很常见的一个应用场景就是,固定页面右侧的 “返回顶部” 按钮。
如下 HTML 结构中,有一个外层.outer包裹两个块元素:
<div class="outer">
<div class="d d1">D1</div>
<div class="d d2">D2</div>
</div>
给这些元素添加样式作区分:
.outer {
width: 200px;
background-color: gray;
padding: 10px;
}
.d {
width: 100px;
height: 100px;
}
.d1 {
background-color: orange;
}
.d2 {
background-color: lightblue;
}
给.d1实现固定定位position: fixed:
.d1 {
background-color: orange;
position: fixed;
left: 0;
top: 0;
}
页面的展示效果如下:
分析一下,固定定位与绝对定位有一定的相似性:
- 固定定位是相对于根元素的,或说固定在浏览器视窗。
- 固定定位是脱离文档流的。
- 固定定位能与浮动共存。
- 固定定位元素作为定位元素。
粘性定位
粘性定位很常见的一个应用场景就是看文章时贴在页面顶部的章节信息。
如下 HTML 结构中,这里有 3 个外层.outer都分别包裹两个块元素:
<div class="outer">
<div class="d d1">第一章 第1节</div>
<div class="d d2">content content content content</div>
</div>
<div class="outer">
<div class="d d1">第一章 第2节</div>
<div class="d d2">hello hello hello hello</div>
</div>
<div class="outer">
<div class="d d1">第一章 第3节</div>
<div class="d d2">world world world world</div>
</div>
给这些元素添加样式作区分:
.outer {
width: 200px;
background-color: gray;
padding: 10px;
margin-top: 10px;
}
.d {
width: 100px;
height: 100px;
}
.d1 {
background-color: orange;
}
.d2 {
background-color: lightblue;
}
给.d1实现粘性定位position: sticky:
.d1 {
background-color: orange;
position: sticky;
top: 0;
}
开始看起来并没有什么特别之处,不过在浏览器在滚动时,当粘性定位的元素即将超出视窗时元素会被固定住,直到其父元素即将超出视窗时才会跟随父元素移动。
粘性定位的特点:
- 粘性定位的定位参考其最近的 “有滚动机制” 的祖先元素。
- 不会脱离文档流,它是用于窗口滚动时的一种定位方式。
定位的层级
各个定位方式都是平级的,但是可以通过设置z-index(z轴高度)改变层级。
.d1 {
z-index: 1;
}
- 定位的层级比普通元素层级高。
- 平级之间的层级,依据后来者居上原则。
- 通过
z-index调整层级,无单位。 - 只有定位元素才能设置
z-index。
定位的其他应用
绝对定位元素充满其父元素
让没有设置宽高的绝对定位元素充满其父元素(包含块)。
如下 HTML 结构中,一个.outer包裹着一个块元素:
<div class="outer">
<div class="d d1">D1</div>
</div>
给.d1添加绝对定位,并让其上下左右偏移都为0:
.outer {
width: 200px;
height: 200px;
background-color: gray;
padding: 10px;
position: relative;
}
.d1 {
background-color: orange;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
页面展示如下:
绝对定位元素水平垂直居中
让有宽高的绝对定位元素水平垂直居中于其父元素(包含块)。
如下 HTML 结构中,一个.outer包裹着一个块元素:
<div class="outer">
<div class="d d1">D1</div>
</div>
给.d1添加绝对定位,并让其上下左右偏移都为0,同时外边距也都为0:
.outer {
width: 200px;
height: 200px;
background-color: gray;
position: relative;
}
.d1 {
width: 100px;
height: 100px;
background-color: orange;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
页面展示如下: