×

CSS3酷炫动画:手把手教您使用纯CSS制作蜡烛动画

作者:Terry2021.02.07来源:Web前端之家浏览:6818评论:0
关键词:htlm5css3动画

通过此动画,我们将使用一些基本的CSS绘图。然后,我们将使用CSS创建触发事件。最后,我们将模拟火焰(尽我们所能!)。

注意:您将在下面看到我使用绝对定位和变换来定位HTML元素,这是使用CSS绘制时的好技巧。

下面是我们要使用CSS绘制的内容:

12.jpg

如果愿意,您可以跟着我。我已经建立了一个基础笔,它建立了一切的基础。

因此,我们首先绘制蜡烛的底座(桌子表面)。

我们将为表的颜色和宽度使用一些SCSS变量:

// table dimensions
$tableWidth: 280px;
$tableHeight: 10px;
$tableBackground: #8b4513;

该表基本上是div具有某些尺寸的。

我们可以将HTML更新为如下所示:

<div class="wrapper">
  <div class="table"></div>
</div>

现在,我们添加一些基本的SCSS(用于transform将表格居中):

.table {
  position: absolute;
  left: 50%;
  top: 50%;
  width: $tableWidth;
  height: $tableHeight;
  background: $tableBackground;
  transform: translate(-50%, -50%);
  z-index: 2;
}

这看起来有些毫无生气。CSS绘图的技巧是使用box-shadow,因此我们将其添加到:

.table {
  ....
  box-shadow: 0px 2px 5px #111;
}

现在,您应该具有:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS蜡烛动画 - Web前端之家https://www.jiangweishan.com</title>
    <style>
     body {
  margin: 0;
}

.wrapper {
  background-color: #2a2a35;
  height: 100vh;
  width: 100vw;
}

.table {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 280px;
  height: 10px;
  background: #8b4513;
  transform: translate(-50%, -50%);
  z-index: 2;
  box-shadow: 0px 2px 5px #111;
}



    </style>
</head>
<body>
    

    

  <div class="wrapper">
    <div class="table"></div>
  </div>

    <script>
        
</script>
</body>
</html>

太棒了!

现在让我们在那张桌子上放一支蜡烛。我们将为我们的蜡烛尺寸和颜色设置一些SCSS变量(随意使用您想要的任何尺寸):

// candle
$candleWidth: 35px;
$candleHeight: 130px;
$candleBorderColor: #673c63;
$stickWidth: 3px;
$stickHeight: 15px;

如果检查一下我之前显示的蜡烛的图像,您会发现它本质上是div一个border上面有一根大棒的蜡烛。首先让我们自己绘制蜡烛。

我们首先更新HTML:

<div class="wrapper">
  <div class="candle">
  </div>
  <div class="table"></div>
</div>

现在,我们添加我们的CSS(同样,box-shadow这里是技巧):

.candle {
  position: absolute;
  left: 50%;
  top: 50%;
  width: $candleWidth;
  height: $candleHeight;
  background: #fff;
  transform-origin: center right;
  transform: translate(-50%, -100%);
  box-shadow: -2px 0px 0px #95c6f2 inset;
  border: 3px solid $candleBorderColor;
}

我们有蜡烛!

现在,我们在上面添加棍子(我们已经在上面包括了尺寸)。

我们首先需要将其添加到我们的HTML中:

<div class="wrapper">
  <div class="candle">
    <div class="candle-stick"></div>
  </div>
  <div class="table"></div>
</div>

CSS(这里没什么花哨的):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS蜡烛动画 - Web前端之家https://www.jiangweishan.com</title>
    <style>
     body {
  margin: 0;
}

.wrapper {
  background-color: #2a2a35;
  height: 100vh;
  width: 100vw;
}

.table {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 280px;
  height: 10px;
  background: #8b4513;
  transform: translate(-50%, -50%);
  z-index: 2;
  box-shadow: 0px 2px 5px #111;
}

.candle {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 35px;
  height: 130px;
  background: #fff;
  transform-origin: center right;
  transform: translate(-50%, -100%);
  box-shadow: -2px 0px 0px #95c6f2 inset;
  border: 3px solid #673c63;
}

.candle-stick {
  width: 3px;
  height: 15px;
  background: #673c63;
  position: absolute;
  left: 50%;
  top: 0%;
  background: #673c63;
  border-radius: 8px;
  transform: translate(-50%, -100%);
}



    </style>
</head>
<body>
    

    

  <div class="wrapper">
    <div class="candle">
      <div class="candle-stick"></div>
    </div>
    <div class="table"></div>
  </div>

    <script>
        
</script>
</body>
</html>

如您所见,这里没有动画,因此让我们开始制作动画。

我们将首先添加一个按钮,该按钮会将背景颜色从浅色更改为深色(我们已经设置了这些SCSS变量—$lightBackground$darkBackground)。将此添加到HTML的最顶部:

<input id="toggle" type="checkbox">
<label for="toggle">Trigger Candle</label>

这会给我们一个不太吸引人的复选框和标签。因此,让我们对其进行样式设置,使其看起来更好一些:

label {
  background: #a5d6a7;
  padding: 0.5rem 1rem;
  border-radius: 0.5rem;
  position: absolute;
  font: 900 24px/1.4 -system-ui, sans-serif;
  transform: translate(50%, 50%);
  cursor: pointer;
}

这为标签提供了一些样式,但是我们也想从视图中隐藏复选框。现在,我们可以通过将hidden属性添加到复选框HTML来做到这一点。但是,这会使键盘导航器无法访问该复选框,因此更好的选择是将其移出视线。首先,让我们.visually-hidden为复选框HTML添加一个类:


<input id="toggle" type="checkbox" class="visually-hidden">

然后,使用此CSS将复选框移到左侧:

.visually-hidden {
  position: absolute;
  left: -100vw;
}

当复选框具有焦点时,我们还提供视觉提示:


input:checked + label {
  outline: 1px dotted red;
}

(如果您想知道为什么在HTML中将放置在input之前label,现在您知道为什么了。这样我们就可以使用同级选择器(+)。稍后再使用。)

现在,您可能不喜欢按钮周围的红色虚线轮廓,但我将留给您提出更好的建议。(例如,您可以改为更改标签的背景色。)

这是我们现在拥有的:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS蜡烛动画 - Web前端之家https://www.jiangweishan.com</title>
    <style>
     body {
  margin: 0;
}

.wrapper {
  background-color: #2a2a35;
  height: 100vh;
  width: 100vw;
}

.table {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 280px;
  height: 10px;
  background: #8b4513;
  transform: translate(-50%, -50%);
  z-index: 2;
  box-shadow: 0px 2px 5px #111;
}

.candle {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 35px;
  height: 130px;
  background: #fff;
  transform-origin: center right;
  transform: translate(-50%, -100%);
  box-shadow: -2px 0px 0px #95c6f2 inset;
  border: 3px solid #673c63;
}

.candle-stick {
  width: 3px;
  height: 15px;
  background: #673c63;
  position: absolute;
  left: 50%;
  top: 0%;
  background: #673c63;
  border-radius: 8px;
  transform: translate(-50%, -100%);
}

label {
  background: #a5d6a7;
  padding: 0.5rem 1rem;
  border-radius: 0.5rem;
  position: absolute;
  font: 900 24px/1.4 -system-ui, sans-serif;
  transform: translate(50%, 50%);
  cursor: pointer;
}

.visually-hidden {
  position: absolute;
  left: -100vw;
}

input:checked + label {
  outline: 1px dotted red;
}



    </style>
</head>
<body>
  <input id="toggle" type="checkbox"  class="visually-hidden">
  <label for="toggle">Trigger Candle</label>
  <div class="wrapper">
    <div class="candle">
      <div class="candle-stick"></div>
    </div>
    <div class="table"></div>
  </div>

<script>
        
</script>
</body>
</html>

让我们根据是否选中复选框来更改页面背景。我们可以通过使用常规的同级选择器来执行此操作而无需使用JavaScript ~

#toggle:checked ~ .wrapper {
  background: $lightBackground;}

现在我们还可以添加一个过渡,使过渡更加平滑:

.wrapper {
  background-color: $darkBackground;
  height: 100vh;
  width: 100vw;
  transition: background-color 0.6s ease;}

我们现在有这个:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS蜡烛动画 - Web前端之家https://www.jiangweishan.com</title>
    <style>
     body {
  margin: 0;
}

.wrapper {
  background-color: #2a2a35;
  height: 100vh;
  width: 100vw;
  transition: background-color 0.6s ease;
}

.table {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 280px;
  height: 10px;
  background: #8b4513;
  transform: translate(-50%, -50%);
  z-index: 2;
  box-shadow: 0px 2px 5px #111;
}

.candle {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 35px;
  height: 130px;
  background: #fff;
  transform-origin: center right;
  transform: translate(-50%, -100%);
  box-shadow: -2px 0px 0px #95c6f2 inset;
  border: 3px solid #673c63;
}

.candle-stick {
  width: 3px;
  height: 15px;
  background: #673c63;
  position: absolute;
  left: 50%;
  top: 0%;
  background: #673c63;
  border-radius: 8px;
  transform: translate(-50%, -100%);
}

label {
  background: #a5d6a7;
  padding: 0.5rem 1rem;
  border-radius: 0.5rem;
  position: absolute;
  font: 900 24px/1.4 -system-ui, sans-serif;
  transform: translate(50%, 50%);
  cursor: pointer;
}

.visually-hidden {
  position: absolute;
  left: -100vw;
}

input:checked + label {
  outline: 1px dotted red;
}

#toggle:checked ~ .wrapper {
  background: #ffffe0;
}



    </style>
</head>
<body>
  <input id="toggle" type="checkbox"  class="visually-hidden">
  <label for="toggle">Trigger Candle</label>
  <div class="wrapper">
    <div class="candle">
      <div class="candle-stick"></div>
    </div>
    <div class="table"></div>
  </div>

<script>
        
</script>
</body>
</html>

我们要做的另一件事是在背景明亮时添加火焰。

和以前一样,我们设置SCSS变量:

// flame
$flameHeight: 20px;
$flameWidth: 16px;
$flameColor1: #e25822;
$flameColor2: #e2b822;

让我们还更新HTML以使其包含火焰:

<label for="toggle">Trigger Candle</label>
<input id="toggle" type="checkbox" hidden>
<div class="wrapper">
  <div class="candle">
    <div class="candle-stick"></div>
     <div class="flame"></div>
  </div>
  <div class="table"></div>
</div>


我们的火焰底数需要使用border-radius八个值。在绘制复杂形状时,Fancy Border Radius Generator网站非常适合border-radius为您生成。

所以这是我们的CSS(border-radius是关键部分):

.flame {
  width: $flameWidth;
  height: $flameHeight;
  background: #673c63;
  position: absolute;
  left: 50%;
  top: 0%;
  background: $flameColor1;
  transform: translate(-50%, -170%);
  border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
}

现在,我们可以添加一些动画,使其像真实的火焰一样闪烁。我们将在两种颜色($flameColor1$flameColor2)之间更改火焰,并且还将在左右两侧稍微改变位置。首先,这是关键帧代码:

@keyframes fire-flicker {
  from {
    background: $flameColor1;
    left: 47%;
  }

  to {
    background: $flameColor2;
    left: 53%;
  }
}

然后,我们需要将此动画添加到flame类中:

animation: fire-flicker 0.2s infinite linear;

现在,我们的火焰将闪烁:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS蜡烛动画 - Web前端之家https://www.jiangweishan.com</title>
    <style>
     body {
  margin: 0;
}

.wrapper {
  background-color: #2a2a35;
  height: 100vh;
  width: 100vw;
  transition: background-color 0.6s ease;
}

.table {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 280px;
  height: 10px;
  background: #8b4513;
  transform: translate(-50%, -50%);
  z-index: 2;
  box-shadow: 0px 2px 5px #111;
}

.candle {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 35px;
  height: 130px;
  background: #fff;
  transform-origin: center right;
  transform: translate(-50%, -100%);
  box-shadow: -2px 0px 0px #95c6f2 inset;
  border: 3px solid #673c63;
}

.candle-stick {
  width: 3px;
  height: 15px;
  background: #673c63;
  position: absolute;
  left: 50%;
  top: 0%;
  background: #673c63;
  border-radius: 8px;
  transform: translate(-50%, -100%);
}

label {
  background: #a5d6a7;
  padding: 0.5rem 1rem;
  border-radius: 0.5rem;
  position: absolute;
  font: 900 24px/1.4 -system-ui, sans-serif;
  transform: translate(50%, 50%);
  cursor: pointer;
}

.visually-hidden {
  position: absolute;
  left: -100vw;
}

input:checked + label {
  outline: 1px dotted red;
}

#toggle:checked ~ .wrapper {
  background: #ffffe0;
}

.flame {
  width: 16px;
  height: 20px;
  background: #673c63;
  position: absolute;
  left: 50%;
  top: 0%;
  background: #e25822;
  transform: translate(-50%, -170%);
  border-radius: 50% 50% 50% 50%/60% 60% 40% 40%;
  animation: fire-flicker 0.2s infinite linear;
}

@keyframes fire-flicker {
  from {
    background: #e25822;
    left: 47%;
  }
  to {
    background: #e2b822;
    left: 53%;
  }
}



    </style>
</head>
<body>
  <input id="toggle" type="checkbox"  class="visually-hidden">
  <label for="toggle">Trigger Candle</label>
  <div class="wrapper">
    <div class="candle">
      <div class="candle-stick"></div>
      <div class="flame"></div>
    </div>
    <div class="table"></div>
  </div>

<script>
        
</script>
</body>
</html>

随时尝试改善它,因为它可能会更好!

好吧,让我们做进一步的调整。当背景较暗时,我们将关闭火焰。

我们将使用它opacity来实现这一目标。在flame课程上,添加不透明度。我们还将向其添加一个过渡,使其与匹配background

.flame {
    ...
    opacity: 0;
    transition: opacity 0.6s ease;
  }

然后,我们可以使用SCSS的功能以及checked状态的一些嵌套:


#toggle:checked ~ .wrapper {
    background: $lightBackground;
    .flame {
      opacity: 1;
    }
  }

现在,火焰仅在明亮的背景下显示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS蜡烛动画 - Web前端之家https://www.jiangweishan.com</title>
    <style>
     body {
  margin: 0;
}

.wrapper {
  background-color: #2a2a35;
  height: 100vh;
  width: 100vw;
  transition: background-color 0.6s ease;
}

.table {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 280px;
  height: 10px;
  background: #8b4513;
  transform: translate(-50%, -50%);
  z-index: 2;
  box-shadow: 0px 2px 5px #111;
}

.candle {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 35px;
  height: 130px;
  background: #fff;
  transform-origin: center right;
  transform: translate(-50%, -100%);
  box-shadow: -2px 0px 0px #95c6f2 inset;
  border: 3px solid #673c63;
}

.candle-stick {
  width: 3px;
  height: 15px;
  background: #673c63;
  position: absolute;
  left: 50%;
  top: 0%;
  background: #673c63;
  border-radius: 8px;
  transform: translate(-50%, -100%);
}

label {
  background: #a5d6a7;
  padding: 0.5rem 1rem;
  border-radius: 0.5rem;
  position: absolute;
  font: 900 24px/1.4 -system-ui, sans-serif;
  transform: translate(50%, 50%);
  cursor: pointer;
}

.visually-hidden {
  position: absolute;
  left: -100vw;
}

input:checked + label {
  outline: 1px dotted red;
}

#toggle:checked ~ .wrapper {
  background: #ffffe0;
}
#toggle:checked ~ .wrapper .flame {
  opacity: 1;
}

.flame {
  width: 16px;
  height: 20px;
  background: #673c63;
  position: absolute;
  left: 50%;
  top: 0%;
  background: #e25822;
  transform: translate(-50%, -170%);
  border-radius: 50% 50% 50% 50%/60% 60% 40% 40%;
  animation: fire-flicker 0.2s infinite linear;
  opacity: 0;
  transition: opacity 0.6s ease;
}

@keyframes fire-flicker {
  from {
    background: #e25822;
    left: 47%;
  }
  to {
    background: #e2b822;
    left: 53%;
  }
}



    </style>
</head>
<body>
  <input id="toggle" type="checkbox"  class="visually-hidden">
<label for="toggle">Trigger Candle</label>
<div class="wrapper">
  <div class="candle">
    <div class="candle-stick"></div>
    <div class="flame"></div>
  </div>
  <div class="table"></div>
</div>

<script>
        
</script>
</body>
</html>

最后,标签的“触发蜡烛”文本有点平淡。我们可以做很多事情!因此,让我们改进标签,使文本在“ Lumos”和“ Nox”之间切换–当然是受哈利·波特的启发!

首先,我们可以将标签更改为不包含文本(我们将content在其中添加文本):

<label for="toggle"></label>

现在,我们将添加一些CSS来切换文本:


label::after {
  content: "Lumos";
}

#toggle:checked ~ label::after {
  content: "Nox";
}

为了阻止标签跳动,让我们添加以下样式:


label {
    ...
    min-width: 100px;
    text-align: center;
}

我们终于得到它了。我们的蜡烛动画完成了-几乎没有JavaScript!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS蜡烛动画 - Web前端之家https://www.jiangweishan.com</title>
    <style>
     body {
        margin: 0;
      }

      .wrapper {
        background-color: #2a2a35;
        height: 100vh;
        width: 100vw;
        transition: background-color 0.6s ease;
      }

      .table {
        position: absolute;
        left: 50%;
        top: 50%;
        width: 280px;
        height: 10px;
        background: #8b4513;
        transform: translate(-50%, -50%);
        z-index: 2;
        box-shadow: 0px 2px 5px #111;
      }

      .candle {
        position: absolute;
        left: 50%;
        top: 50%;
        width: 35px;
        height: 130px;
        background: #fff;
        transform-origin: center right;
        transform: translate(-50%, -100%);
        box-shadow: -2px 0px 0px #95c6f2 inset;
        border: 3px solid #673c63;
      }

      .candle-stick {
        width: 3px;
        height: 15px;
        background: #673c63;
        position: absolute;
        left: 50%;
        top: 0%;
        background: #673c63;
        border-radius: 8px;
        transform: translate(-50%, -100%);
      }

      label {
        background: #a5d6a7;
        padding: 0.5rem 1rem;
        border-radius: 0.5rem;
        position: absolute;
        font: 900 24px/1.4 -system-ui, sans-serif;
        transform: translate(50%, 50%);
        cursor: pointer;
        min-width: 100px;
        text-align: center;
      }

      .visually-hidden {
        position: absolute;
        left: -100vw;
      }

      input:checked + label {
        outline: 1px dotted red;
      }

      #toggle:checked ~ .wrapper {
        background: #ffffe0;
      }
      #toggle:checked ~ .wrapper .flame {
        opacity: 1;
      }

      .flame {
        width: 16px;
        height: 20px;
        background: #673c63;
        position: absolute;
        left: 50%;
        top: 0%;
        background: #e25822;
        transform: translate(-50%, -170%);
        border-radius: 50% 50% 50% 50%/60% 60% 40% 40%;
        animation: fire-flicker 0.2s infinite linear;
        opacity: 0;
        transition: opacity 0.6s ease;
      }

      @keyframes fire-flicker {
        from {
          background: #e25822;
          left: 47%;
        }
        to {
          background: #e2b822;
          left: 53%;
        }
      }
      label::after {
        content: "Lumos";
      }

      #toggle:checked ~ label::after {
        content: "Nox";
      }



    </style>
</head>
<body>
  <input id="toggle" type="checkbox"  class="visually-hidden">
  <label for="toggle"></label>
  <div class="wrapper">
    <div class="candle">
      <div class="candle-stick"></div>
      <div class="flame"></div>
    </div>
    <div class="table"></div>
  </div>

<script>
        
</script>
</body>
</html>

您的支持是我们创作的动力!
温馨提示:本文作者系Terry ,经Web前端之家编辑修改或补充,转载请注明出处和本文链接:
https://jiangweishan.com/article/donghua20210207a2.html

网友评论文明上网理性发言 已有0人参与

发表评论: