css动画库
纯css实现炫酷水晶螺旋加载动画
Dec 20, 2025
154 阅读
官方团队
# 纯 CSS 实现炫酷水晶螺旋加载动画
今天分享一个非常有意思的 CSS 加载动画效果。它不需要任何 JavaScript,仅仅通过 CSS3 的动画延迟(Animation Delay)和 3D 透视(Perspective),就能组合出一个类似水晶螺旋上升的视觉效果。
### 效果预览
这是代码的实际运行效果:
***donghua
<style>
.container {
display: flex;
align-items: center;
justify-content: center;
}
.loader {
position: relative;
width: 200px;
height: 200px;
perspective: 800px;
}
.crystal {
position: absolute;
top: 50%;
left: 50%;
width: 60px;
height: 60px;
opacity: 0;
transform-origin: bottom center;
transform: translate(-50%, -50%) rotateX(45deg) rotateZ(0deg);
animation: spin 4s linear infinite, emerge 2s ease-in-out infinite alternate,
fadeIn 0.3s ease-out forwards;
border-radius: 10px;
visibility: hidden;
}
@keyframes spin {
from {
transform: translate(-50%, -50%) rotateX(45deg) rotateZ(0deg);
}
to {
transform: translate(-50%, -50%) rotateX(45deg) rotateZ(360deg);
}
}
@keyframes emerge {
0%,
100% {
transform: translate(-50%, -50%) scale(0.5);
opacity: 0;
}
50% {
transform: translate(-50%, -50%) scale(1);
opacity: 1;
}
}
@keyframes fadeIn {
to {
visibility: visible;
opacity: 0.8;
}
}
.crystal:nth-child(1) {
background: linear-gradient(45deg, #003366, #336699);
animation-delay: 0s;
}
.crystal:nth-child(2) {
background: linear-gradient(45deg, #003399, #3366cc);
animation-delay: 0.3s;
}
.crystal:nth-child(3) {
background: linear-gradient(45deg, #0066cc, #3399ff);
animation-delay: 0.6s;
}
.crystal:nth-child(4) {
background: linear-gradient(45deg, #0099ff, #66ccff);
animation-delay: 0.9s;
}
.crystal:nth-child(5) {
background: linear-gradient(45deg, #33ccff, #99ccff);
animation-delay: 1.2s;
}
.crystal:nth-child(6) {
background: linear-gradient(45deg, #66ffff, #ccffff);
animation-delay: 1.5s;
}
</style>
<div class="container">
<div class="loader">
<div class="crystal"></div>
<div class="crystal"></div>
<div class="crystal"></div>
<div class="crystal"></div>
<div class="crystal"></div>
<div class="crystal"></div>
</div>
</div>
***
### 代码原理解析
这个效果的核心在于 CSS(层叠样式表)的几个关键属性的组合使用。下面我们把这段代码拆解开来,看看它到底“写了什么”。
#### 1. 舞台搭建:`.loader`
```css
.loader {
position: relative;
width: 200px;
height: 200px;
perspective: 800px;
}
```
这里最关键的属性是 `perspective: 800px;`。
* **作用**:它定义了观察者与 z=0 平面的距离。
* **效果**:没有它,所有的旋转看起来都是扁平的(2D);加上它之后,元素在旋转时就会产生“近大远小”的 3D 空间感。
#### 2. 主角登场:`.crystal`
```css
.crystal {
/* ...定位属性... */
transform-origin: bottom center;
transform: translate(-50%, -50%) rotateX(45deg) rotateZ(0deg);
animation: spin 4s linear infinite, emerge 2s ease-in-out infinite alternate,
fadeIn 0.3s ease-out forwards;
}
```
这是每一个“水晶片”的样式:
* **`transform-origin: bottom center;`**:这是旋转的轴心。我们让它围绕底部中心旋转,而不是默认的中心点,这样转起来才有“甩出去”的感觉。
* **`rotateX(45deg)`**:让水晶片稍微倾斜一点,配合上面的 `perspective`,看起来就像是躺在空间里。
* **`animation`**:这里同时应用了三个动画!
1. `spin`:负责 360 度旋转。
2. `emerge`:负责忽大忽小、忽隐忽现的呼吸感。
3. `fadeIn`:负责入场时的渐显。
#### 3. 灵魂所在:`nth-child` 与 `animation-delay`
```css
.crystal:nth-child(1) { animation-delay: 0s; }
.crystal:nth-child(2) { animation-delay: 0.3s; }
/* ...以此类推... */
```
这是整个动画看起来像“螺旋”的关键。
* 我们有 6 个完全一样的 `.crystal` div。
* 如果不加延迟,它们会重叠在一起同时运动。
* 通过给每个子元素增加 **0.3s 的延迟**,它们运动的节奏就被错开了。第一个先动,第二个紧随其后……这就形成了一条流畅的视觉轨迹。
#### 4. 渐变配色
每个水晶片都使用了不同深度的蓝色渐变:
```css
background: linear-gradient(45deg, #003366, #336699);
```
从深蓝到浅蓝,模拟了光线折射的效果,增加了科技感。
### 完整代码
你可以直接复制以下代码到你的项目中使用:
```html
<style>
.container {
display: flex;
align-items: center;
justify-content: center;
}
.loader {
position: relative;
width: 200px;
height: 200px;
perspective: 800px;
}
.crystal {
position: absolute;
top: 50%;
left: 50%;
width: 60px;
height: 60px;
opacity: 0;
transform-origin: bottom center;
transform: translate(-50%, -50%) rotateX(45deg) rotateZ(0deg);
animation: spin 4s linear infinite, emerge 2s ease-in-out infinite alternate,
fadeIn 0.3s ease-out forwards;
border-radius: 10px;
visibility: hidden;
}
@keyframes spin {
from {
transform: translate(-50%, -50%) rotateX(45deg) rotateZ(0deg);
}
to {
transform: translate(-50%, -50%) rotateX(45deg) rotateZ(360deg);
}
}
@keyframes emerge {
0%,
100% {
transform: translate(-50%, -50%) scale(0.5);
opacity: 0;
}
50% {
transform: translate(-50%, -50%) scale(1);
opacity: 1;
}
}
@keyframes fadeIn {
to {
visibility: visible;
opacity: 0.8;
}
}
.crystal:nth-child(1) {
background: linear-gradient(45deg, #003366, #336699);
animation-delay: 0s;
}
.crystal:nth-child(2) {
background: linear-gradient(45deg, #003399, #3366cc);
animation-delay: 0.3s;
}
.crystal:nth-child(3) {
background: linear-gradient(45deg, #0066cc, #3399ff);
animation-delay: 0.6s;
}
.crystal:nth-child(4) {
background: linear-gradient(45deg, #0099ff, #66ccff);
animation-delay: 0.9s;
}
.crystal:nth-child(5) {
background: linear-gradient(45deg, #33ccff, #99ccff);
animation-delay: 1.2s;
}
.crystal:nth-child(6) {
background: linear-gradient(45deg, #66ffff, #ccffff);
animation-delay: 1.5s;
}
</style>
<div class="container">
<div class="loader">
<div class="crystal"></div>
<div class="crystal"></div>
<div class="crystal"></div>
<div class="crystal"></div>
<div class="crystal"></div>
<div class="crystal"></div>
</div>
</div>
```