在前端开发中,堆叠是根据HTML元素在一个假想的Z轴上的值,按优先顺序排序的概念。堆叠顺序通常受到一些CSS属性值的影响,如position 、z-index 、opacity ,以及其他。
在本教程中,我们将演示使用堆叠技术在HTML中构建令人惊叹的UI的一些最佳实践。
前提条件
要跟上本教程,你需要。
- 对网络开发有基本了解
- 熟悉CSS和HTML
- 在你的系统中安装一个网络浏览器,例如Chrome浏览器
- 在你的开发机器上安装一个代码编辑器,如VS Code。
在我们真正开始工作之前,让我们考虑两种情况。
- 你想创建两个重叠的元素。
position要做到这一点,你只需将第一个元素的relative,而将后者设置为绝对值,对吗? - 比方说,你想在你的网页上添加一个粘性的
navbar。为此,你只需将它的z-index设置为高于所有其他元素的值。
在这两种情况之间,就是CSS中堆叠的力量。考虑到这一线索,让我们深入探讨一下如何使用CSS堆叠技术来构建简单和复杂的重叠UI。
使用CSSposition 属性进行堆叠
在本节中,我们将使用HTML和CSS的position 属性来构建三个重叠的div。
首先,在你的工作目录中创建一个名为stacking_with_position_property 的新文件夹。导航到该文件夹并创建两个文件:index.html 和styles.css 。
接下来,在你的代码编辑器中打开index.html ,添加下面的代码。
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Stacking with Position Property</title>
</head>
<body></body>
</html>
接下来,让我们把stylesheet 与index.html 联系起来。在HTML文件的head 部分中添加下面的代码。
<head>
...
<link rel="stylesheet" href="styles.css">
...
</head>
现在让我们开始构建HTML元素。将下面的代码添加到body 标签中,以创建三个div。
<div class="rectangle_wrapper">
<div class="rectangle1">Div 1</div>
<div class="rectangle2">Div 2</div>
<div class="rectangle3">Div 3</div>
</div>
在这里,我们创建了一个包装器来容纳三个div,其类名为rectangle1,rectangle2, 和rectangle3 。
接下来,打开styles.css ,添加下面的代码来覆盖浏览器默认的padding 和margin 。
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
max-width: 1100px;
margin: 0 auto;
}
这里我们使用* 关键字,将所有默认的margin 和padding 设置为0 。然后我们使用body 关键字,将网页的max-width 设置为1100px ,以确保浏览器视口内的所有元素不会溢出到极致。
接下来,将下面的CSS添加到styles.css ,为divs设置样式。
...
.rectangle_wrapper {
height: 50px;
width: 200px;
position: relative;
}
.rectangle1,
.rectangle2,
.rectangle3 {
position: absolute;
width: 100%;
height: 100%;
border-radius: 10px;
}
.rectangle1 {
top: 20px;
background: #6b9080;
}
.rectangle2 {
top: 30px;
background: #eaf4f4;
}
.rectangle3 {
top: 40px;
background: #cce3de;
}
现在,如果你在浏览器中打开index.html ,该网页应该看起来像下面的截图。

现在你知道如何使用CSSposition 属性在HTML中堆叠多个元素了。
这个例子之所以能够实现,是因为我们把position: relative 添加到了我们的父元素。每当一个元素被设置为position: relative ,该div内的每一个其他元素与position: absolute ,都将被绝对地相对于该单元放置。
这是一个古老的堆叠元素的概念,但它在所有的浏览器中都能稳定地工作,所以强烈推荐。
用CSS网格堆叠
在现代网站开发中,CSS网格是一种常见的堆叠元素的方法。它可以通过网格布局,用最少的代码在网页中轻松放置元素。在本节中,我们将演示如何通过增强我们在上一节中创建的元素来使用CSS网格堆叠元素。
再次,浏览你在上一节中创建的stacking_with_position_property 文件夹。复制一份HTML和CSS文件,并删除所有CSS,除了* 和body 关键字。
现在,让我们将下面的代码添加到styles.css 。
.rectangle_wrapper{
height: 100%;
display: grid;
grid-template-columns: repeat(1fr, 3);
grid-template-areas: "rec1 rec2 rec3";
border: 3px dotted brown;
padding: 20px;
margin: 30px;
}
.rectangle1{
width: 100%;
grid-area: rec1 ;
background: #6b9080;
}
.rectangle2{
width: 100%;
grid-area: rec2 ;
background: #eaf4f4;
}
.rectangle3{
width: 100%;
grid-area: rec3 ;
background: #cce3de;
}
首先,我们将rectangle_wrapper 类设置为display: grid 。然后,我们将grid-template-column 设置为repeat(1fr, 3) ,它在三列中重复一个片段。接下来,我们用grid-template-areas 来定义网格列(rec1 rec2 rec3),然后将每个矩形类grid-area 设置为其相应的列。
有了这个造型,每个矩形类都成为rectangle_wrapper 的直接子代,允许矩形堆叠成一条水平线。
在你的浏览器中打开index.html 。网页看起来应该与下面的截图相似。

注意,需要给父类一个相对位置,因为它自动允许其下级元素重叠。CSS网格可以用来创建三维布局,父类内的所有元素都将相对绝对于父类单元。
把这一切放在一起。构建一个三维按钮
在本节中,我们将使用上面演示的技术来构建一个三维按钮。下面是最终的按钮的样子。

你可能会想,为什么我们没有使用box-shadow 或border 等属性来设计上面的例子。原因是为这些属性制作动画是很昂贵的,而且没有为平滑过渡腾出空间。
复制一个index.html 文件,用下面的代码替换body 标签内的代码。
<button class="clickable">
<span class="front"> Click Me </span>
</button>
接下来,用下面的代码替换styles.css 中的代码。
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
max-width: 1100px;
display: flex;
justify-content: center;
align-items: center;
justify-items: center;
}
这里,我们将body 伪类设置为display:flex,justify-content: center,align-items: center, 和justify-items: center 。这将确保它的所有后代将被定位在网页的中心。
接下来,在styles.css ,添加以下代码,创建按钮MVP。
...
.clickable {
background: #2d6a4f;
border-radius: 12px;
border: none;
padding: 0;
cursor: pointer;
outline-offset: 4px;
}
.front {
display: block;
padding: 12px 42px;
border-radius: 12px;
font-size: 1.4rem;
color: #fff;
background: #52b788;
transform: translateY(-6px);
}
.clickable:active .front {
transform: translate(-2px);
}
button 元素有一个深绿色的背景,代表按钮的底层。我们通过表示border:none ,删除了按钮的默认边框。.front 类代表按钮的前景层,它的背景是较浅的绿色。
我们使用transform: translate 这个CSS属性,在按钮每次处于:active 状态时,创造一个滑动的效果。形成的按钮的MVP应该类似于下面的截图。

这个按钮看起来已经是3D的了!接下来,让我们给按钮添加一个悬停状态。将下面的代码添加到styles.css ,创建一个hover 的效果。
...
.front{
...
will-change: transform;
transition: transform 250ms;
}
.clickable:hover .front {
transform: translateY(-8px);
}
注意,我们添加了will-change:transform 属性。这是一个最佳做法,可以让悬停动画被硬件加速。最终的结果应该类似于下面的GIF。

接下来,让我们为按钮添加阴影,以增强3D效果。为了实现这一点,我们必须重组index.html 中的标记。
<button class="clickable">
<span class="shadow"></span>
<span class="edge"></span>
<span class="front"> Click Me </span>
</button>
以前,.clickable 类是边缘层。随着两个层的引入,我们必须使用position: relative ,使.clickable 类成为.shadow,.edge, 和.front 类的父类。
用下面的代码替换.clickable 和.front 类的代码。
.clickable {
position: relative;
background: transparent;
border: none;
padding: 0;
cursor: pointer;
}
.front {
display: block;
padding: 12px 42px;
border-radius: 12px;
font-size: 1.4rem;
color: #fff;
background: #52b788;
transform: translateY(-4px);
will-change: transform;
transition: transform 250ms;
}
我们只是简单地使用了我们之前回顾的堆叠技术,通过将.clickable 类设置为position: relative ,来堆叠按钮层。这样做,我们暗示每个降级元素都应该放在它的上面。
让我们添加.shadow 和.edge 类以及它们的hover 效果。
.shadow {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 12px;
transform: translateY(2px);
background: #ced4da;
}
.edge {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 12px;
background: #2d6a4f;
}
.clickable:hover .front {
transform: translateY(-6px);
}
.clickable:hover .shadow {
transform: translateY(4px);
}
.clickable:active .front {
transform: translate(-2px);
}
.clickable:active .shadow {
transform: translate(1px);
}
在这里,我们强迫.shadow 和.edge 类从它们的父类的width 和height 中获取100% ,在这种情况下,父类是.clickable 类。我们还设置了它们的top:0 和left:0 ,以确保它们被定位在它们父类的中心,没有默认的边距。
每次用户悬停按钮时,.shadow 类向下移动4px ,.front 类向上移动6px ,显示出.edge 类。现在,这个按钮在悬停时应该看起来像下面的gif图。

我们完全依靠DOM顺序来堆叠HTML元素--不需要z-index 。这已经揭示了在CSS中堆叠和定位重叠元素的最佳实践的公平份额。
我们可以通过给.shadow 类添加一个blur 的效果来完成这个按钮,使它看起来更柔和、更吸引人。将下面的代码添加到.shadow 类中。
.shadow {
...
filter: blur(4px);
}
该按钮的最终结果应该是这样的。

你可以在这里看一下这部分的完整源代码。整个项目可以在这个GitHub repo中找到。
总结
利用本教程中所学到的技术,你可以在新的和现有的网络应用中只用CSS和HTML来实现具有3D效果的复杂重叠元素。
如果你想在我们今天所讲的原则基础上再进一步,你可能想尝试实现一个粘性标题,或者两个重叠的轮子,一个顺时针旋转,一个逆时针旋转。本教程中所涉及的准则是你最好的选择--让我知道它的效果如何。
CSS中堆叠元素的最佳实践》一文出现在LogRocket博客上。