制作仅使用 CSS 的加载器是我最喜欢的任务之一。看着这些无限动画总令人满意。当然,还有很多技术和方法可以制作它们——无需去 CodePen 查看更多,您就能看到有多少种方法。不过,在本文中,我们将看到如何使用最少的代码制作单元素加载器。
我制作了一系列超过 500 个单 div 加载器,在本系列的四篇文章中,我将分享我用来创建其中许多加载器的技巧。我们将涵盖大量的示例,展示微小的调整如何导致有趣的变化,以及需要编写多少代码才能实现这一切!
单元素加载器系列
- 单元素加载器:旋转器——您在此处
- 单元素加载器:圆点
- 单元素加载器:条形
- 单元素加载器:进入 3D
在第一篇文章中,我们将创建一个更常见的加载器模式:旋转条形
以下是方法
对该加载器进行简单实现的方法是,为每个条形创建一个元素,并将其包装在一个父元素中(总共九个元素),然后使用opacity
和transform
来获得旋转效果。
但是,我的实现只需要一个元素
<div class="loader"></div>
……以及 10 个 CSS 声明
.loader {
width: 150px; /* control the size */
aspect-ratio: 1;
display: grid;
mask: conic-gradient(from 22deg, #0003, #000);
animation: load 1s steps(8) infinite;
}
.loader,
.loader:before {
--_g: linear-gradient(#17177c 0 0) 50%; /* update the color here */
background:
var(--_g)/34% 8% space no-repeat,
var(--_g)/8% 34% no-repeat space;
}
.loader:before {
content: "";
transform: rotate(45deg);
}
@keyframes load {
to { transform: rotate(1turn); }
}
让我们分解一下
乍一看,代码可能看起来很奇怪,但您会发现它比您想象的要简单。第一步是定义元素的尺寸。在本例中,它是一个150px
的正方形。我们可以使用aspect-ratio
,这样无论元素的宽度如何,它都保持正方形。
.loader {
width: 150px; /* control the size */
aspect-ratio: 1; /* make height equal to width */
}
在构建 CSS 加载器时,我总是尝试为控制整体大小使用一个值。在本例中,它是width
,我们将要介绍的所有计算都将参考该值。这使我能够更改单个值以控制加载器。始终能够轻松调整加载器的大小,而无需调整许多其他值,这一点至关重要。
接下来,我们将使用渐变来创建条形。这是最棘手的部分!让我们使用一个渐变来创建两个条形,如下所示
background: linear-gradient(#17177c 0 0) 50%/34% 8% space no-repeat;

我们的渐变是用一种颜色和两个颜色停止定义的。结果是纯色,没有淡出或过渡。大小等于34%
宽和8%
高。它也被放置在中心(50%
)。技巧是使用关键字值space
——这会复制渐变,使我们总共得到两个条形。
来自规范
图像会尽可能多次重复,以适合背景定位区域,且不会被剪裁,然后图像会间隔开以填充该区域。第一个和最后一个图像接触区域的边缘。
我使用的宽度等于34%
,这意味着我们不能有超过两个条形(3*34%
大于100%
),但如果有两个条形,我们将有空隙(100% - 2 * 34% = 32%
)。该空隙被放置在两个条形之间的中心。换句话说,我们使用一个宽度等于33%
到50%
之间的渐变,以确保我们至少有两个条形,并且它们之间有一点空隙。值space
会正确地将它们放置在我们想要的位置。
我们做同样的事情,再制作一个类似的渐变,以获得另外两个条形,分别位于顶部和底部,这会使我们的background
属性值成为
background:
linear-gradient(#17177c 0 0) 50%/34% 8% space no-repeat,
linear-gradient(#17177c 0 0) 50%/8% 34% no-repeat space;
我们可以使用 CSS 变量对其进行优化,以避免重复
--_g: linear-gradient(#17177c 0 0) 50%; /* update the color here */
background:
var(--_g)/34% 8% space no-repeat,
var(--_g)/8% 34% no-repeat space;
所以,现在我们有四个条形,并且由于 CSS 变量,我们可以只编写一次颜色值,这使得以后很容易更新(就像我们对加载器大小所做的那样)。
为了创建剩余的条形,让我们利用.loader
元素及其::before
伪元素来获得另外四个条形,总共八个。
.loader {
width: 150px; /* control the size */
aspect-ratio: 1;
display: grid;
}
.loader,
.loader::before {
--_g: linear-gradient(#17177c 0 0) 50%; /* update the color here */
background:
var(--_g)/34% 8% space no-repeat,
var(--_g)/8% 34% no-repeat space;
}
.loader::before {
content: "";
transform: rotate(45deg);
}
请注意使用display: grid
。这使我们能够依靠网格的默认stretch
对齐方式来使伪元素覆盖其父元素的整个区域;因此,我们无需在其上指定尺寸——另一个技巧可以减少代码量,并且避免我们处理大量值!
现在让我们将伪元素旋转45deg
以定位剩余的条形。将鼠标悬停在以下演示上,以查看技巧
设置不透明度
我们要做的是创建一个印象,即有一个条形在圆形路径上移动时留下了逐渐消失的条形轨迹。现在我们需要使用 CSSmask
和圆锥形渐变来操作条形的透明度,以创建该轨迹,如下所示
mask: conic-gradient(from 22deg,#0003,#000);
为了更好地查看技巧,让我们将其应用于一个全色框
红色的透明度以顺时针方向逐渐增加。我们将它应用于我们的加载器,我们就有了透明度不同的条形

实际上,每个条形似乎都消失了,因为它们被渐变蒙版,并且位于两个半透明颜色之间。在运行时,这几乎是不可察觉的,因此可以说所有条形都具有相同的颜色,但透明度不同。
旋转
让我们应用旋转动画来获得我们的加载器。请注意,我们需要的是步进动画,而不是连续动画,这就是为什么我使用steps(8)
的原因。8
仅仅是条形的数量,因此可以根据条形的数量来更改该值。
.loader {
animation: load 3s steps(8) infinite;
}
/* Same as before: */
@keyframes load {
to { transform: rotate(1turn) }
}
就这样!我们只有使用一个元素和几行 CSS 代码就创建了加载器。我们可以通过调整一个值来轻松控制其大小和颜色。
由于我们只使用了::before
伪元素,所以我们可以通过使用::after
添加另外四个条形,总共 12 个条形,代码几乎相同
我们将伪元素的旋转更新为考虑30deg
和60deg
,而不是45deg
,同时使用 12 步动画,而不是 8 步动画。我还将高度减少到5%
,而不是8%
,以使条形更细一些。
另外,请注意我们在伪元素上使用了grid-area: 1/1
。这使我们能够将它们放置在彼此相同的区域中,彼此堆叠。
猜猜看?我们可以使用另一种实现来获得相同的加载器
你能弄清楚代码背后的逻辑吗?以下是一个提示:不透明度不再使用 CSSmask
来处理,而是使用渐变中的opacity
属性来处理。
为什么不使用圆点代替呢?
我们完全可以这样做
如果您查看代码,您会发现我们现在使用的是径向渐变,而不是线性渐变。除此之外,概念完全相同,蒙版会创建一个透明度的印象,但我们将形状制作成圆形,而不是线条。
以下是说明新渐变配置的图形

如果您使用的是 Safari,请注意演示可能存在错误。这是因为 Safari 目前不支持径向渐变中的at
语法。但我们可以稍微重新配置渐变以克服此问题
.loader,
.loader:before,
.loader:after {
background:
radial-gradient(
circle closest-side,
currentColor 90%,
#0000 98%
)
50% -150%/20% 80% repeat-y,
radial-gradient(
circle closest-side,
currentColor 90%,
#0000 98%
)
-150% 50%/80% 20% repeat-x;
}
更多加载器示例
以下是另一个类似于前一个的旋转器加载器创意。
对于此加载器,我只使用background
和mask
来创建形状(无需伪元素)。我还使用 CSS 变量定义配置,以便能够从同一代码创建许多变体——这是 CSS 变量功能的另一个示例。我写了另一篇关于此技术的文章,如果您想要了解更多详细信息。
请注意,一些浏览器仍然依赖于-webkit-
前缀用于mask-composite
,它有自己的一套值,并且不会在演示中显示旋转器。这里有一个方法可以做到这一点,无需使用mast-composite
,以获得更多浏览器支持。
我还有另一个要给你。
对于这个,我使用background-color
来控制颜色,并使用mask
和mask-composite
来创建最终的形状。

在我们结束之前,这里有一些我之前制作的旋转加载器。我依赖于不同的技术,但仍然使用渐变、蒙版、伪元素等。它可以是一个很好的练习,以弄清楚每个加载器的逻辑,并同时学习新技巧。也就是说,如果你对它们有任何疑问,评论区就在下面。
总结
看看,我们可以用 CSS 做很多事情,只需要一个 div、几个渐变、伪元素和变量。看起来我们创建了很多不同的旋转加载器,但它们基本上都是同一件事,只是略有修改。
这仅仅是一个开始。在这个系列中,我们将研究更多关于创建CSS 加载器的想法和高级概念。
单元素加载器系列
- 单元素加载器:旋转器——您在此处
- 单元素加载器:圆点
- 单元素加载器:条形
- 单元素加载器:进入 3D
我只是想要更新,但这个很酷!
非常棒!
你可以添加一些 a11y,包括
aria-busy="true"
用于辅助技术?https://mdn.org.cn/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-busy
很棒的加载器
很棒的,谢谢分享。不过我希望它们有更少的偏好风格。如果你想要更基本的东西,这里有一堆单色 CSS 加载器:https://onedivloaders.vercel.app.