无需 JavaScript 即可创建强大的 CSS 动画效果

在本文中,我们将探索仅使用 CSS 的 Web 动画世界。我们将首先使用 SVG 和 CSS 的组合创建一个简单的动画。然后,我们将只使用 HTML 和 CSS 创建另外几个动画。我们还将讨论何时需要调用 JavaScript 以及 CSS 的局限性。

在本文结束时,您将能够使用 CSS 来创建动画,而不是使用 JavaScript。您还可以确定何时需要使用 JavaScript 来创建动画。

为了充分利用本文,我们假设您至少具备 CSS 和 HTML 的核心知识。如果您刚开始进行 Web 开发,这里有一些很好的学习和获得帮助的资源,例如sitePoint 上的学习资源、非常有用的SitePoint 论坛以及freecodecamp。

绘图效果动画

这是一个令人印象深刻的动画,看似容易创建。下面是我们的目标截图。

文章图片1

我们首先需要为我们的徽标创建 SVG:

 xmlns="http://www.w3.org/2000/svg" width="279.15" height="343.95" overflow="visible" stroke="#000" stroke-width="1">  d="M110.57 248.64c-22.7-21.25-45.06-42.09-67.31-63.06-11.73-11.06-23.32-22.26-34.87-33.51C-2.6 141.35-2.86 128 8.02 117.42 47.67 78.82 87.46 40.35 127.21 1.84c.46-.44 1.03-.77 2.47-1.84 12.52 13.66 25.06 27.34 37.1 40.47-4.44 4.76-10.06 11.31-16.21 17.33-22.69 22.2-45.56 44.22-68.34 66.32-7.89 7.66-7.97 13.48.11 21.07 19.38 18.19 38.85 36.29 58.37 54.33 7.53 6.96 7.75 12.42.32 19.64-10.01 9.72-20.05 19.4-30.46 29.48z"/>  d="M150.02 343.95c-13.41-13.03-26.71-25.97-40.2-39.08 1.23-1.32 2.19-2.44 3.24-3.46 27.8-26.95 55.61-53.89 83.42-80.83 8.32-8.05 8.41-13.92-.01-21.79-19.54-18.27-39.14-36.47-58.77-54.63-6.52-6.04-6.76-12.11-.37-18.33 10.24-9.96 20.52-19.87 31.15-30.16 6.33 5.89 12.53 11.58 18.65 17.37 27.53 26.03 55.07 52.05 82.52 78.16 12.57 11.96 12.66 24.78.33 36.75-38.99 37.85-78.04 75.64-117.07 113.45-.82.79-1.71 1.51-2.89 2.55z"/>

这是一个设置了 SVG的Pen 。随意分叉它,以便您可以按照以下步骤进行操作。

有了我们的 SVG,我们现在fill-opacity将0. 稍后我们将对此进行动画处理:

svg {  fill-opacity: 0;}

(更新笔)

我们现在可以专注于绘制 SVG。我们将通过使用 CSSstroke-dashoffset和stroke-dasharray属性来实现这一点。

该stroke-dasharray属性控制用于使笔划成为路径的间隙和虚线的模式。例如,stroke-dasharray: 10应用于 SVG 中的路径会创建一个虚线效果,其中笔画和间隙长度为 10 个像素:

现在,对于我们在这里创建的动画,我们希望我们的 gap 和 dash 与我们的path. 也就是说,我们的标志轮廓的整个长度将被认为是“一个破折号”,可以这么说,一个间隙也将是轮廓的整个长度。我们的想法是,我们将从徽标轮廓作为间隙开始,然后在轮廓中作为破折号进行动画处理。

但是徽标的轮廓有多长?处理这个问题的一个简单方法是设置长度。pathLength="1"让我们通过添加到每个路径来编辑我们的 SVG 代码:

 … <path pathLength="1" d="M110.57 … > …

(更新笔)

这使得绘制动画变得更加容易。现在我们已经设置了pathLength,我们还可以stroke-dasharray在1CSS 中设置 :

svg path {  stroke-dasharray: 1;}

(更新笔)

现在,这里似乎没有任何变化,但没关系。徽标每个部分的整个路径现在只是一个大破折号。(您可以通过pathLength="1"从其中一条路径中移除来进行实验。它会突然变成一条 1px 线和间隙的虚线。)

我们现在可以使用stroke-dashoffset,它指定我们应该在破折号模式多远的地方开始破折号。在我们的例子中,我们想要设置stroke-dashoffset为1,所以我们从 agap而不是 a开始dash。由于我们每个间隙的长度是我们的整个长度,path我们现在将看到一个空白屏幕:

svg path {  stroke-dasharray: 1;  stroke-dashoffset: 1;  }

我们现在可以动画stroke-dashoffset回到0,这将给出一个绘图效果:

svg path {  stroke-dasharray: 1;  stroke-dashoffset: 1;    animation: draw 2s forwards;}@keyframes draw {  from {    stroke-dashoffset: 1;  }  to {    stroke-dashoffset: 0;  }}

凉爽的!有了这个,我们现在有了这个:

要完成我们的动画,我们只需要在我们的fill-opacity:

svg {  width: 40%;  fill-opacity: 0;  // we set a delay of 2s so it won't start until our drawing is finished  animation: fadeOpacity 2s forwards 2s;}@keyframes fadeOpacity {  from {    fill-opacity: 0;  }  to {    fill-opacity: 1;  }}

我们现在有了最终的动画:

我敢打赌,这比你想象的要容易得多!我知道
stroke-dashoffsetandstroke-dasharray属性可能有点令人困惑,但是当你将你path的长度设置为 时1,它们更容易使用。

这是 CSS 与 SVG 结合的一个简单示例。现在让我们在下一个示例中进一步推动这一点。

CSS 蜡烛动画

所以我们在最后一个例子中有点作弊,因为我们使用了 SVG。对于下一个示例,我们将仅使用 CSS(当然还有 HTML)。

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

兴奋的?害怕的?我两个都是!所以我们走吧!

通过出色的 Jhey Thompkins,我学到了很多关于使用 CSS 绘图的知识。我建议查看这篇很棒的文章以获取额外的阅读。

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

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

文章图片2

如果你愿意,可以跟着我。我已经设置了一个基础笔,它具有一切设置的根。

所以让我们首先画出蜡烛的底部(桌子表面)。

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

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

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

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

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;}

你现在应该有这个:

惊人的!

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

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

如果您检查我之前展示的蜡烛的图像,您会发现它本质上是div一个大border的,顶部有一根棍子。让我们先画出蜡烛本身。

我们首先更新我们的 HTML:

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 中:

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

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

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

我们已经成功绘制了蜡烛:

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

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

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

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

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中添加一个类:

"toggle" type="checkbox" class="visually-hidden">

然后我们用这个 CSS 将复选框移到左边:

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

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

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

(如果你想知道为什么我在 HTML 中放置了input之前的label,现在你知道为什么了。这样我们就可以使用兄弟选择器+(

现在,您可能不喜欢按钮周围的红色虚线轮廓,但我会让您想出更好的东西。(例如,您可以改为更改标签的背景颜色。)

这是我们现在所拥有的:

让我们根据复选框是否被选中来更改页面的背景。我们可以在不使用 JavaScript 的情况下使用通用的同级选择器来做到这一点~:

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

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

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

我们现在有这个:

凉爽的!

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

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

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

让我们也更新 HTML 以包含火焰:

<label for="toggle">Trigger Candlelabel><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;

我们的火焰现在会闪烁:

随意尝试改进它,因为它可能会更好!

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

我们将使用它opacity来实现这一点。在flame类上,添加不透明度。我们还将为其添加一个过渡,使其与background:

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

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

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

现在火焰只出现在浅色背景中:

最后,标签的“触发蜡烛”文本有点乏味。我们可以做很多事情!所以让我们改进我们的标签,让文本在“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 代码!

作为一个额外的好处,如果你不喜欢 SCSS 并且宁愿尝试 CSS 自定义属性(又名变量),这里是我们蜡烛演示的纯 CSS 版本。没有太大的不同!(当然,如果您愿意,也可以在上面的每个 Pen 上查看编译后的 CSS。打开CSS Settings > CSS Preprocessor > None。)

脉冲动画

这是一个涉及较少的动画,但展示了您只需一点 CSS 即可完成的工作。

要开始,我们需要做一个圆圈。让我们首先添加一些 HTML:

class="pulse">div>

现在我们可以使用一些 CSS 来创建我们的圆圈:

.pulse {  position:absolute;  left:50%;  top:50%;  transform:scale(1.5,1.5) translate(-50%,-50%);  height: 150px;  width: 150px;  background: #a83f39;  border-radius: 50%;}

这是我们目前所拥有的:

要创建脉冲动画,我们使用该box-shadow属性。如果您以前从未使用box-shadow过,Mozilla 有一些很棒的文档:

@keyframes pulse {  0% {    box-shadow: 0 0 0 0 rgba(168, 63, 57, 0.4);  }  70% {      box-shadow: 0 0 0 50px rgba(168, 63, 57, 0);  }  100% {      box-shadow: 0 0 0 150px rgba(168, 63, 57, 0);  }}

要使用此动画,我们只需将其添加到.pulse:

.pulse {   ....   animation: pulse 2s infinite;}

我们现在已经创建了脉冲动画。不会太破旧吧?

你不能用 CSS 做什么?

因此,尽管我很喜欢 CSS 动画,但有些事情是不可能或很难做到的。

  • 您无法通过 CSS 动画进行搜索,或跳转到动画的某个部分。所以根据用户点击的位置来定制你的动画是非常困难的。要使用 JavaScript 实现这一点,我建议使用出色的GreenSock 库。
  • 沿曲线制作动画非常困难。
  • 涉及滚动的动画也很棘手,尽管Chris Coyier解释了如何只用一点点 JavaScript 就可以做到这一点。
  • 根据自动计算的高度对元素的高度进行动画处理。
  • 对多个动画进行排序也相当困难。您可以通过延迟来实现这一点,但对于具有大量移动部件的复杂动画来说,这可能非常困难。同样,使用 GreenSock 库要容易得多。

以上是 CSS 动画的一些主要限制。其中一些可以通过使用 SVG 绕过,但总体而言,使用 JavaScript 更容易实现上述目标。

结论

我希望通过阅读这篇文章,您对 CSS 动画有一个全新的理解。我在这篇文章中展示的只是表面而已。我将在下面列出一些鼓舞人心的笔,您可以查看!

无需 JavaScript 即可创建强大的 CSS 动画效果

在本文中,我们将探索仅使用 CSS 的 Web 动画世界。我们将首先使用 SVG 和 CSS 的组合创建一个简单的动画。然后,我们将只使用 HT

Web前端:2022年最好的JavaScript框架是什么?

它用于创建 Web 应用程序和 REST API,它速度快,也是一个轻量级且可扩展的 Node.js Web 应用程序框架,提供了用于创建 We

4种JavaScript中不同迭代对象的方法

英文 | https://javascript.plaine… test: , test: false,};for (let [key, value] of bject.entries(obj)) { console.log(key, value);}//test atit//test /…

【浏览器】HTML、CSS和JS如何变成页面的?

我们经常写 HTML 、 CSS 和 JavaScript ,写好这些之后,我们就会在浏览器中看到页面,那浏览器究竟在这背后做了一些什么事情呢?本篇文章将揭晓答案!

Android 屏幕适配方案

近日作家六六发布微博称,其通过百度查一个上海美国领事馆官网的地址,然后发现搜索结果中有比较多的骗子广告。