元素重叠定位的几种方法
前言
在网页中,常常会出现元素重叠的情况,例如下面这张图片,它的下面有一段表示这张图片内容的描述,这种定位方式在网页中经常会用到,比如轮播图、弹窗等等。

本文将介绍几种常用的元素重叠定位的方法。
绝对定位
首先第一种方法——绝对定位,非常常用的方法,不展开介绍了。
<figure>
<img src="./night-sky.jpg" />
<figcaption>Trees against purple night sky</figcaption>
</figure>
figure {
position: relative;
display: inline-block;
}
figcaption {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background-color: #0009;
color: white;
text-align: center;
line-height: 2;
}
margin 负值
第二种方法是使用负值的 margin,也比较简单,不展开。
<figure>
<img src="./night-sky.jpg" />
<figcaption>Trees against purple night sky</figcaption>
</figure>
figure {
display: inline-block;
}
figcaption {
background-color: #0009;
color: white;
text-align: center;
line-height: 2;
margin-top: -2rem;
/* 背景层叠顺序较低 */
position: relative;
}
Grid 布局
重点讲一下第三种方法——使用 Grid 布局,这种是比较推荐的方法。
我们给容器设置为 display: inline-grid 或者 grid,然后 grid 子项的网格区域设置为同一个区域,它们就会自然而然的重叠在一起了。
<figure>
<img src="./night-sky.jpg" />
<figcaption>Trees against purple night sky</figcaption>
</figure>
figure {
display: inline-grid;
}
figure > img,
figure > figcaption {
/* 还可以简写为 grid-area: 1 / 2 */
grid-area: 1 / 1 / 2 / 2;
}
figcaption {
align-self: end;
text-align: center;
background-color: #0009;
color: white;
line-height: 2;
}
原理
grid 子项都占用同一个网格就会重叠
优点
控制方便
比如说我希望黑色蒙层覆盖整个图片,我们设置为 align-self: stretch,就可以了。
cssfigcaption { align-self: stretch; }
Trees against purple night sky 层叠上下文关系和包含块关系没有变化
第二个优点是相比于之前的绝对定位,其容器元素的层叠上下文关系和包含块关系是没有任何变化的,在某些场景下这个就特别的适用。
container 方法
第四种方法叫 container 方法,这个估计没几个人知道。
它的结构是这样的:
<figure>
<span><img src="./night-sky.jpg" /></span>
<figcaption>Trees against purple night sky</figcaption>
</figure>
figure {
display: inline-flex;
}
figure > span {
container-type: inline-size;
}
figcaption {
width: 256px;
align-self: end;
text-align: center;
background-color: #0009;
color: white;
line-height: 2;
z-index: 1;
}
我们把图片通过一个 span 元素包起来,然后设置它的 container-type 为 inline-size,这个时候,它就能自然重叠了。
原理
所有具有尺寸收缩特性的元素,设置为容器元素后,其宽度尺寸都会变为 0。
例如任意 display 是 inline-* 的元素,浮动元素,绝对定位元素,flex 子项,或 width: fit-content 元素等。
凡是满足这样条件的元素,设置 container-type 为 inline-size 后,那宽度都是 0。我们利用了这个特性,实现了重叠效果。
总结
最后总结一下各个方法的适用场景:
通常没有意外的话我们就使用这个绝对定位方法,兼容性更好。
margin 负值它适用于不能绝对定位,但同时尺寸已知的场景。
如果既不能使用绝对定位,尺寸又不是固定的,我们可以使用 Grid 布局,同时还有一种场景就是如果你的项目不需要考虑到兼容性的场景,然后又想展示自己在 CSS 这块的功力,就是所谓的“装逼”给同事、领导看,我们也可以使用 Grid 布局。
container 容器元素因为兼容性还不是特别的好,目前只适合用在学习场景中。