在CSS中堆叠元素的最佳实践

3,829 阅读8分钟

在前端开发中,堆叠是根据HTML元素在一个假想的Z轴上的值,按优先顺序排序的概念。堆叠顺序通常受到一些CSS属性值的影响,如positionz-indexopacity ,以及其他。

在本教程中,我们将演示使用堆叠技术在HTML中构建令人惊叹的UI的一些最佳实践。

前提条件

要跟上本教程,你需要。

  • 对网络开发有基本了解
  • 熟悉CSS和HTML
  • 在你的系统中安装一个网络浏览器,例如Chrome浏览器
  • 在你的开发机器上安装一个代码编辑器,如VS Code。

在我们真正开始工作之前,让我们考虑两种情况。

  1. 你想创建两个重叠的元素。position 要做到这一点,你只需将第一个元素的relative ,而将后者设置为绝对值,对吗?
  2. 比方说,你想在你的网页上添加一个粘性的navbar 。为此,你只需将它的z-index 设置为高于所有其他元素的值。

在这两种情况之间,就是CSS中堆叠的力量。考虑到这一线索,让我们深入探讨一下如何使用CSS堆叠技术来构建简单和复杂的重叠UI。

使用CSSposition 属性进行堆叠

在本节中,我们将使用HTML和CSS的position 属性来构建三个重叠的div。

首先,在你的工作目录中创建一个名为stacking_with_position_property 的新文件夹。导航到该文件夹并创建两个文件:index.htmlstyles.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>

接下来,让我们把stylesheetindex.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 ,添加下面的代码来覆盖浏览器默认的paddingmargin

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}
body {
  max-width: 1100px;
  margin: 0 auto;
}

这里我们使用* 关键字,将所有默认的marginpadding 设置为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 ,该网页应该看起来像下面的截图。

Stacked divs Using the CSS position Property

现在你知道如何使用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 。网页看起来应该与下面的截图相似。

Stacked divs Using CSS Grid

注意,需要给父类一个相对位置,因为它自动允许其下级元素重叠。CSS网格可以用来创建三维布局,父类内的所有元素都将相对绝对于父类单元。

把这一切放在一起。构建一个三维按钮

在本节中,我们将使用上面演示的技术来构建一个三维按钮。下面是最终的按钮的样子。

Finished 3D Button Demo

你可能会想,为什么我们没有使用box-shadowborder 等属性来设计上面的例子。原因是为这些属性制作动画是很昂贵的,而且没有为平滑过渡腾出空间。

复制一个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 Button MVP

这个按钮看起来已经是3D的了!接下来,让我们给按钮添加一个悬停状态。将下面的代码添加到styles.css ,创建一个hover 的效果。

...
.front{
  ...
  will-change: transform;
  transition: transform 250ms;
}
.clickable:hover .front {
  transform: translateY(-8px);
}

注意,我们添加了will-change:transform 属性。这是一个最佳做法,可以让悬停动画被硬件加速。最终的结果应该类似于下面的GIF。

3D Button with Hover Transform Added

接下来,让我们为按钮添加阴影,以增强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 类从它们的父类的widthheight 中获取100% ,在这种情况下,父类是.clickable 类。我们还设置了它们的top:0left:0 ,以确保它们被定位在它们父类的中心,没有默认的边距。

每次用户悬停按钮时,.shadow 类向下移动4px.front 类向上移动6px ,显示出.edge 类。现在,这个按钮在悬停时应该看起来像下面的gif图。

3D Button with Shadow Class Added

我们完全依靠DOM顺序来堆叠HTML元素--不需要z-index 。这已经揭示了在CSS中堆叠和定位重叠元素的最佳实践的公平份额。

我们可以通过给.shadow 类添加一个blur 的效果来完成这个按钮,使它看起来更柔和、更吸引人。将下面的代码添加到.shadow 类中。

.shadow {
...
  filter: blur(4px);
}

该按钮的最终结果应该是这样的。

Finished 3D Button Demo

你可以在这里看一下这部分的完整源代码。整个项目可以在这个GitHub repo中找到

总结

利用本教程中所学到的技术,你可以在新的和现有的网络应用中只用CSS和HTML来实现具有3D效果的复杂重叠元素。

如果你想在我们今天所讲的原则基础上再进一步,你可能想尝试实现一个粘性标题,或者两个重叠的轮子,一个顺时针旋转,一个逆时针旋转。本教程中所涉及的准则是你最好的选择--让我知道它的效果如何。

CSS中堆叠元素的最佳实践》一文出现在LogRocket博客上。