想做流星动画加一点动态氛围感,不想引入臃肿的 JS 库,也不想用现成的动效插件,用纯 CSS也能实现流星不断划过夜空的背景动画。核心是CSS 的
animation关键帧、伪元素和基础定位,零 JS 依赖、轻量流畅,还能根据页面风格灵活调整流星的颜色、轨迹、速度,适配个人博客、小众展示页等各种场景。实现思路很简单,小光点做流星核心 + 伪元素做渐变拖尾 + 关键帧控制划过运动 + 差异化配置让流星不同步。
一、实现思路
整个动效的核心就 5 点,不用复杂的 CSS 属性:
- 用一个容器撑起全屏,作为流星的承载层,放在页面最底层不遮挡内容;
- 用小方块做流星的核心光点,通过圆角变成圆形,作为流星的视觉核心;
- 用伪元素
::after实现流星的拖尾,通过线性渐变linear-gradient做「实色到透明」的效果,模拟流星划过的光影拖尾(这是流星效果的灵魂); - 用
@keyframes定义animation关键帧,结合transform的translate和rotate实现流星的线性划过,配合opacity实现流星「出现 – 划过 – 消失」的自然过渡; - 用
nth-child给每颗流星配置不同的初始位置、动画时长、延迟时间,让流星不会同步运动,实现「满天流星」的效果。
二、完整可复用代码(HTML+CSS)
基于核心思路做了简单完善,保留了最简洁的结构,适配全屏背景,代码里加了详细注释,可以直接复制到项目中,HTML 只需要写流星容器和流星元素,CSS 负责所有样式和动效,数量可以自己加(建议 10-20 颗,太多会影响性能,太少氛围感不足)。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS流星划过背景动画</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* 页面基础样式:深色夜空背景,方便凸显流星 */
body {
width: 100vw;
height: 100vh;
background: #0a0e17;
overflow: hidden;
}
/* 流星容器:全屏承载,放在页面最底层 */
.meteor-container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
user-select: none; /* 禁止选中流星元素,提升体验 */
z-index: -1; /* 放在页面最底层,不遮挡其他内容 */
pointer-events: none; /* 禁止流星区域的鼠标事件,不影响页面操作 */
}
/* 流星基础样式:核心光点 */
.meteor {
position: absolute;
width: 2px;
height: 2px;
background-color: #fff; /* 流星核心光点,纯白色更亮 */
border-radius: 50%; /* 圆形光点,更贴合流星视觉 */
opacity: 0; /* 初始透明,让流星通过动画自然出现 */
animation: meteor-slide linear infinite; /* 线性运动,速度不变,无限循环 */
}
/* 伪元素:流星拖尾(核心效果) */
.meteor::after {
content: "";
position: absolute;
top: 0;
left: 0.8px; /* 微调左偏移,让拖尾和核心光点居中对齐 */
width: 1px; /* 拖尾宽度,比光点细,更自然 */
height: 120px; /* 拖尾长度,可根据需求调整 */
border-radius: 2px; /* 轻微圆角,拖尾边缘不生硬 */
/* 金白渐变拖尾:从纯白到浅金再到透明,比纯白带光影感 */
background: linear-gradient(
to bottom,
rgba(255, 255, 255, 1) 0%,
rgba(255, 255, 255, 0.8) 10%,
rgba(205, 158, 17, 0.5) 30%,
rgba(205, 158, 17, 0) 100%
);
/* 拖尾和流星核心一起运动,不偏移 */
transform: inherit;
}
/* 关键帧:流星划过的核心动效 */
@keyframes meteor-slide {
0% {
/* 初始状态:指定位置,完全不透明,开始运动 */
transform: translate(0, 0) rotate(225deg);
opacity: 1;
}
30% {
/* 划过中期:保持不透明,让流星有足够的可见时间 */
opacity: 1;
}
100% {
/* 结束状态:平移到目标位置,完全透明,模拟流星消失 */
transform: translate(-380px, 200px) rotate(225deg);
opacity: 0;
}
}
/* 不同流星的差异化配置:位置/动画时长/延迟,核心是避免同步 */
.meteor:nth-child(1) {
top: 10%;
left: 20%;
animation-duration: 2s; /* 动画时长,越短速度越快 */
animation-delay: 0s; /* 延迟出现,避免同时划过 */
}
.meteor:nth-child(2) {
top: 30%;
left: 60%;
animation-duration: 1.8s;
animation-delay: 1s;
}
.meteor:nth-child(3) {
top: 20%;
left: 80%;
animation-duration: 2.2s;
animation-delay: 0.5s;
}
.meteor:nth-child(4) {
top: 50%;
left: 10%;
animation-duration: 3s;
animation-delay: 3s;
}
.meteor:nth-child(5) {
top: 70%;
left: 90%;
animation-duration: 2.5s;
animation-delay: 1.5s;
}
.meteor:nth-child(6) {
top: 40%;
left: 50%;
animation-duration: 1.9s;
animation-delay: 2s;
}
.meteor:nth-child(7) {
top: 60%;
left: 30%;
animation-duration: 2.8s;
animation-delay: 2.5s;
}
.meteor:nth-child(8) {
top: 80%;
left: 70%;
animation-duration: 2.1s;
animation-delay: 0.8s;
}
</style>
</head>
<body>
<!-- 流星容器 -->
<div class="meteor-container">
<!-- 流星元素:需要几颗就加几个,建议10-20颗 -->
<div class="meteor"></div>
<div class="meteor"></div>
<div class="meteor"></div>
<div class="meteor"></div>
<div class="meteor"></div>
<div class="meteor"></div>
<div class="meteor"></div>
<div class="meteor"></div>
</div>
<!-- 页面其他内容:会自动显示在流星上层 -->
<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: #fff; font-size: 24px;">
流星背景下的内容
</div>
</body>
</html>
三、核心代码细节解析
上面的代码看似简单,但每一个属性的设置都是为了让流星效果更真实,这里挑最关键的几个部分解析,理解后就能轻松自定义效果了。
1. 流星容器:meteor-container的关键属性
这个容器是流星的「舞台」,几个属性缺一不可:
position: absolute+top:0+left:0+width:100%+height:100%:让容器撑满整个父容器(页面),流星可以在全屏范围内运动;user-select: none:禁止用户鼠标选中流星元素,避免页面操作时出现不必要的选中框;z-index: -1:将容器放在页面最底层,保证页面的其他内容(文字、按钮、图片)都能正常显示在流星上层;- 新增
pointer-events: none:禁止流星区域的鼠标事件,避免流星遮挡导致页面按钮、链接无法点击,这是容易忽略的细节。
2. 流星核心:.meteor的小光点设计
流星的核心光点不用太大,
2px*2px的尺寸刚好,太大会显得臃肿,像星星而不是流星;配合border-radius: 50%变成圆形光点,纯白色#fff的亮度足够,在深色背景下更显眼。初始
opacity: 0是为了让流星通过关键帧动画自然出现,而不是页面加载时就全部显示,更贴合真实流星的出现规律。3. 灵魂所在:伪元素::after的渐变拖尾
流星的拖尾是整个效果的核心,用伪元素实现的好处是不用额外增加 HTML 标签,让结构更简洁,关键设置解析:
left: 0.8px:因为流星核心是2px宽,拖尾是1px宽,微调左偏移让拖尾和核心光点居中对齐,视觉上更协调;height: 120px:拖尾的长度,可根据需求调整 —— 数值越大拖尾越长,流星的视觉效果越明显,建议 80-150px;linear-gradient渐变:我用了「纯白→浅白→浅金→透明」的渐变,比纯纯白的拖尾多了一点光影感,模拟流星划过的金光效果;如果想要冷色调的流星,直接把金色部分改成浅蓝 / 浅紫即可;transform: inherit:让拖尾继承流星核心的transform运动属性,保证拖尾和核心光点一起划过,不会出现偏移。
4. 关键帧动画:meteor-slide的运动逻辑
关键帧定义了流星从「出现→划过→消失」的完整过程,核心是
transform的组合和opacity的过渡:rotate(225deg):这是流星划过的角度,225deg 刚好让流星从右上到左下划过(最符合人们对流星的视觉认知),如果想让流星从左上到右下,可调整为 135deg;translate(-380px, 200px):控制流星的划过轨迹,第一个值是水平向左偏移,第二个值是垂直向下偏移,数值越大,流星的划过范围越广;opacity的变化:0% 时不透明(出现)→30% 时保持不透明(持续划过)→100% 时透明(消失),避免流星突然出现或消失,过渡更自然;animation-timing-function: linear:线性运动,让流星划过的速度保持不变,更贴合真实流星的运动规律。
5. 差异化配置:nth-child让流星「各有个性」
如果所有流星的位置、速度、延迟都一样,会出现「同步划过」的尴尬效果,用
nth-child给每颗流星单独配置属性,就能实现满天流星的杂乱感,核心配置三个属性:top/left:流星的初始出现位置,随机分布在页面的不同区域,避免扎堆;animation-duration:动画时长,数值越短,流星划过的速度越快,建议 1.5s-3s,快慢结合更真实;animation-delay:动画延迟时间,随机设置 0s 到 3s 的延迟,让流星分批出现,不会同时划过。
四、视觉 & 性能优化小技巧
掌握了基础实现后,几个小技巧能让流星效果更自然,同时保证页面性能,避免动效拖慢页面。
1. 视觉优化
- 拖尾长度 / 宽度差异化:可以给部分流星的伪元素单独设置
height/width,比如有的拖尾 100px,有的 150px,有的宽 1px,有的宽 0.8px,让流星有大小之分; - 颜色微调:少数流星可以改成浅蓝(
rgba(135,206,235,0.5)),避免全是金色拖尾的单调感,模拟不同的流星光影; - 划过轨迹微调:给部分流星修改关键帧的
translate数值,比如有的-380px,200px,有的-450px,250px,让划过轨迹有差异。
2. 性能优化
- 控制流星数量:建议 10-20 颗,太多的话会增加浏览器的渲染压力,尤其是低性能设备,太少的话氛围感不足;
- 只用
transform和opacity做动画:这两个属性是 CSS 的合成属性,浏览器只会触发复合层更新,不会触发重绘和回流,是性能最优的动画属性,本次实现全程只用了这两个属性; - 避免复杂样式:流星元素不要加阴影、滤镜等复杂样式,会增加渲染成本,保持样式简洁即可。
五、灵活拓展:适配不同页面风格
基于这个基础实现,只需要修改几个属性,就能适配不同的页面风格,不用重写代码。
1. 冷色调流星(适合科技感 / 简约页面)
把伪元素的渐变颜色改成蓝白色,替换掉金色即可:
.meteor::after {
background: linear-gradient(
to bottom,
rgba(255, 255, 255, 1) 0%,
rgba(255, 255, 255, 0.8) 10%,
rgba(135, 206, 235, 0.5) 30%,
rgba(135, 206, 235, 0) 100%
);
}
2. 短拖尾流星(适合简约 / 轻量页面)
缩短伪元素的拖尾长度,让流星更小巧:
.meteor::after {
height: 80px; /* 从120px改成80px */
}
3. 快速划过的流星(适合活泼 / 动感页面)
整体减小
animation-duration的数值,让所有流星的速度变快:/* 比如把原来的2s改成1.2s,3s改成1.8s */
.meteor:nth-child(1) {
animation-duration: 1.2s;
}
4. 作为 Vue3 组件背景
如果是在 Vue3 项目中使用,只需要把
meteor-container放在组件的根节点,设置position: relative即可,比如:<template>
<div class="blog-container" style="position: relative; width: 100%; height: 100vh;">
<!-- 流星背景 -->
<div class="meteor-container">
<div class="meteor"></div>
<!-- 更多流星 -->
</div>
<!-- 组件内容 -->
<div class="blog-content">
<!-- 你的博客内容 -->
</div>
</div>
</template>
<script setup>
// 组件逻辑
</script>
<style scoped>
/* 复制流星的CSS样式,注意去掉scoped或用:deep()穿透 */
:deep(.meteor-container) {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
user-select: none;
z-index: -1;
pointer-events: none;
}
/* 其他流星样式同理 */
</style>
六、总结
CSS 流星背景动画,就是把基础定位 + 伪元素 + animation 关键帧这三者结合起来,没有用到任何复杂的 CSS 属性,零 JS 依赖,轻量又流畅,非常适合给个人博客、小众展示页增加氛围感。
其实很多看似好看的 CSS 动效,本质都是基础知识点的灵活组合,不用追求炫技的属性,把基础打牢,就能用简单的代码实现想要的效果。这次的代码可以直接复用,也可以灵活调整。
如果想让流星效果更极致,也可以结合 CSS 变量给每颗流星设置随机的拖尾长度、速度,不用一个个写
nth-child,让代码更简洁、拓展性更强。












