大家好,我是前端开发者。在前端技术不断发展的今天,CSS 早已不只是用来布局和美化页面的工具,它还能成为我们创作视觉艺术的画笔。今天给大家带来一个纯 CSS + 原生 JS 实现的交互式深空场景,无需任何图形库,就能在浏览器里呈现出繁星闪烁、星云流动、行星运转、流星划过的沉浸式宇宙画面。 项目已开源,大家可以直接下载运行,也能基于它二次创作属于自己的星空。
一、项目效果与核心亮点
先给大家直观展示项目效果:
- 全屏黑色深空背景,搭配彩色渐变星云,氛围感拉满
- 1000 颗随机大小、随机闪烁的星星,布满整个屏幕
- 50 个彩色星系,随机旋转、发光,层次丰富
- 中心蓝色行星 + 光环,3 颗卫星按不同速度、方向公转
- 随机位置划过的流星,动态感拉满
- 环绕行星的小行星带,持续旋转
- 纯前端实现,无图片、无第三方库,加载极快
核心技术点:
- CSS
@keyframes实现流畅动画 - 径向渐变 / 线性渐变打造星球、星云、流星质感
transform实现 3D 旋转、公转、缩放效果- JS 动态生成大量元素,随机化属性更自然
- 绝对定位 + 层级管理,构建深空立体空间
二、项目完整代码(带详细注释)
1. HTML 结构(搭建宇宙骨架)
HTML 只负责搭建容器,所有视觉元素由 CSS 绘制、JS 动态生成,结构极简清晰。
html
预览
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Cosmic Canvas 深空艺术</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<!-- 宇宙总容器 -->
<div class="space-scene">
<!-- 星星容器 -->
<div class="stars"></div>
<!-- 星系容器 -->
<div class="galaxies"></div>
<!-- 流星容器 -->
<div class="shooting-stars"></div>
<!-- 星云容器 -->
<div class="nebula"></div>
<!-- 行星系统:主行星+光环+卫星 -->
<div class="planet-system">
<div class="planet main-planet"></div>
<div class="planet-ring"></div>
<div class="moon moon1"></div>
<div class="moon moon2"></div>
<div class="moon moon3"></div>
</div>
<!-- 小行星带容器 -->
<div class="asteroid-belt"></div>
</div>
<script src="script.js"></script>
</body>
</html>
2. CSS 样式(绘制宇宙万物)
CSS 是这个项目的核心,负责所有视觉效果、动画、质感的实现,每一行都加了注释,方便理解。
css
/* 全局初始化:清除默认边距,全屏展示,隐藏滚动条 */
body,
html {
margin: 0;
padding: 0;
height: 100%;
/* 隐藏溢出内容,保证星空全屏 */
overflow: hidden;
}
/* 宇宙场景容器:全屏黑色背景,相对定位作为子元素参照物 */
.space-scene {
width: 100%;
height: 100%;
background: #000000;
position: relative;
overflow: hidden;
}
/* 星星+星系公共样式:绝对定位铺满全屏 */
.stars,
.galaxies {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
/* 单个星星样式:白色圆点,闪烁动画 */
.star {
position: absolute;
background-color: #fff;
border-radius: 50%;
/* 闪烁动画:4s无限循环,缓动效果 */
animation: twinkle 4s infinite ease-in-out;
}
/* 单个星系样式:椭圆形状,发光动画 */
.galaxy {
position: absolute;
border-radius: 50%;
/* 发光动画:4s无限交替循环 */
animation: glow 4s infinite alternate;
}
/* 星星闪烁动画:透明度+缩放交替 */
@keyframes twinkle {
0%,
100% {
opacity: 0.5;
transform: scale(1);
}
50% {
opacity: 1;
transform: scale(1.2);
}
}
/* 星系发光动画:阴影渐变,营造光晕 */
@keyframes glow {
0% {
box-shadow: 0 0 2px 1px rgba(255, 255, 255, 0.1);
}
100% {
box-shadow: 0 0 10px 2px rgba(255, 255, 255, 0.3);
}
}
/* 星云效果:多层径向渐变+模糊+透明度,梦幻氛围 */
.nebula {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
/* 多层彩色径向渐变,叠加出星云色彩 */
background: radial-gradient(
circle at 20% 80%,
rgba(255, 0, 100, 0.1) 0%,
transparent 50%
),
radial-gradient(
circle at 80% 20%,
rgba(0, 100, 255, 0.1) 0%,
transparent 50%
),
radial-gradient(
circle at 40% 40%,
rgba(255, 100, 0, 0.1) 0%,
transparent 60%
),
radial-gradient(
circle at 60% 60%,
rgba(100, 0, 255, 0.1) 0%,
transparent 60%
);
/* 模糊处理,柔化边缘 */
filter: blur(20px);
opacity: 0.5;
}
/* 行星系统容器:居中定位,作为行星和卫星的父容器 */
.planet-system {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 300px;
height: 300px;
}
/* 主行星:蓝色渐变,圆形,发光阴影,居中 */
.main-planet {
width: 150px;
height: 150px;
/* 径向渐变打造星球立体感 */
background: radial-gradient(circle at 30% 30%, #4a89dc, #1c3c78);
border-radius: 50%;
/* 外发光,模拟星球光晕 */
box-shadow: 0 0 50px rgba(74, 137, 220, 0.8);
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* 行星光环:3D旋转,半透明边框,模拟土星环效果 */
.planet-ring {
width: 225px;
height: 225px;
border: 10px solid rgba(255, 255, 255, 0.2);
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
/* X轴旋转75度,呈现3D环装效果 */
transform: translate(-50%, -50%) rotateX(75deg);
}
/* 卫星公共样式:圆形,居中定位 */
.moon {
width: 20px;
height: 20px;
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
}
/* 卫星1:金色,30s公转 */
.moon1 {
animation: orbit 30s linear infinite;
background: radial-gradient(circle at 30% 30%, #ffd700, #ffa500);
box-shadow:
inset -2px -2px 4px rgba(0, 0, 0, 0.3),
0 0 8px rgba(255, 215, 0, 0.6);
}
/* 卫星2:蓝色,反向45s公转 */
.moon2 {
animation: orbit 45s linear infinite reverse;
background: radial-gradient(circle at 30% 30%, #add8e6, #4169e1);
box-shadow:
inset -2px -2px 4px rgba(0, 0, 0, 0.3),
0 0 8px rgba(65, 105, 225, 0.6);
}
/* 卫星3:黄色,60s公转 */
.moon3 {
animation: orbit 60s linear infinite;
background: radial-gradient(circle at 30% 30%, #f0e68c, #daa520);
box-shadow:
inset -2px -2px 4px rgba(0, 0, 0, 0.3),
0 0 8px rgba(218, 165, 32, 0.6);
}
/* 卫星公转动画:核心!rotate+translate组合实现圆周运动 */
@keyframes orbit {
0% {
transform: rotate(0deg) translateX(100px) rotate(0deg);
}
100% {
transform: rotate(360deg) translateX(100px) rotate(-360deg);
}
}
/* 流星容器:全屏铺满 */
.shooting-stars {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
/* 流星样式:线性渐变,从白到透明,模拟流星尾迹 */
.shooting-star {
position: absolute;
height: 2px;
background: linear-gradient(90deg, #ffffff, transparent);
/* 流星划过动画 */
animation: shoot 3s ease-out infinite;
}
/* 流星划过动画:斜向移动+透明度消失 */
@keyframes shoot {
0% {
transform: translateX(-100px) translateY(100px);
opacity: 1;
}
70% {
opacity: 1;
}
100% {
transform: translateX(1000px) translateY(-1000px);
opacity: 0;
}
}
/* 小行星带:3D旋转,环形布局 */
.asteroid-belt {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotateX(75deg);
width: 350px;
height: 350px;
border-radius: 50%;
}
/* 小行星样式:灰色小圆点,环形旋转 */
.asteroid {
position: absolute;
background: #555;
border-radius: 50%;
top: 50%;
left: 50%;
/* 旋转中心设置为环的边缘 */
transform-origin: 175px 0;
animation: rotate 20s linear infinite;
}
/* 小行星旋转动画:沿环公转 */
@keyframes rotate {
0% {
transform: rotate(0deg) translateX(175px) rotate(0deg);
}
100% {
transform: rotate(360deg) translateX(175px) rotate(-360deg);
}
}
3. JavaScript(动态生成宇宙元素)
JS 负责批量生成星星、星系、流星、小行星,随机化大小、位置、动画时长,让星空更自然不呆板。
javascript
运行
/**
* 动态创建天体元素:星星、星系、流星、小行星
* 批量生成+随机属性,提升效率与真实感
*/
function createCelestialObjects() {
// 获取所有容器DOM
const starsContainer = document.querySelector(".stars");
const galaxiesContainer = document.querySelector(".galaxies");
const shootingStarsContainer = document.querySelector(".shooting-stars");
const asteroidBelt = document.querySelector(".asteroid-belt");
// 配置元素数量,可自行调整
const starCount = 1000; // 星星数量
const galaxyCount = 50; // 星系数量
const shootingStarCount = 5; // 同时存在的流星数量
const asteroidCount = 100; // 小行星数量
// 星系颜色库
const galaxyColors = ["#FFD700", "#87CEEB", "#FFA500", "#FF69B4", "#00CED1"];
// 1. 生成1000颗星星
for (let i = 0; i < starCount; i++) {
const star = document.createElement("div");
star.className = "star";
// 随机大小:0-2px
star.style.width = star.style.height = `${Math.random() * 2}px`;
// 随机位置:全屏百分比
star.style.left = `${Math.random() * 100}%`;
star.style.top = `${Math.random() * 100}%`;
// 随机动画时长:2-4s
star.style.animationDuration = `${Math.random() * 2 + 2}s`;
// 随机动画延迟:0-4s
star.style.animationDelay = `${Math.random() * 4}s`;
starsContainer.appendChild(star);
}
// 2. 生成50个星系
for (let i = 0; i < galaxyCount; i++) {
const galaxy = document.createElement("div");
galaxy.className = "galaxy";
// 随机大小:5-25px
const size = Math.random() * 20 + 5;
galaxy.style.width = `${size}px`;
galaxy.style.height = `${size / 2}px`;
// 随机位置
galaxy.style.left = `${Math.random() * 100}%`;
galaxy.style.top = `${Math.random() * 100}%`;
// 随机颜色
galaxy.style.backgroundColor = galaxyColors[Math.floor(Math.random() * galaxyColors.length)];
// 随机旋转角度
galaxy.style.transform = `rotate(${Math.random() * 360}deg)`;
galaxiesContainer.appendChild(galaxy);
}
// 3. 生成流星
for (let i = 0; i < shootingStarCount; i++) {
const shootingStar = document.createElement("div");
shootingStar.className = "shooting-star";
// 随机位置
shootingStar.style.left = `${Math.random() * 100}%`;
shootingStar.style.top = `${Math.random() * 100}%`;
// 随机延迟,避免同时出现
shootingStar.style.animationDelay = `${Math.random() * 5}s`;
shootingStarsContainer.appendChild(shootingStar);
}
// 4. 生成小行星
for (let i = 0; i < asteroidCount; i++) {
const asteroid = document.createElement("div");
asteroid.className = "asteroid";
// 随机大小:1-4px
asteroid.style.width = asteroid.style.height = `${Math.random() * 3 + 1}px`;
// 随机动画时长:10-20s
asteroid.style.animationDuration = `${Math.random() * 10 + 10}s`;
asteroid.style.animationDelay = `${Math.random() * 10}s`;
asteroidBelt.appendChild(asteroid);
}
}
// 页面加载完成后执行,确保DOM就绪
window.addEventListener("load", createCelestialObjects);
三、核心技术解析(掘金读者必看)
1. 公转动画实现原理
卫星和小行星的圆周运动是项目核心,用到 CSS transform 组合技巧:
css
transform: rotate(360deg) translateX(100px) rotate(-360deg);
- 第一层
rotate:让元素绕父容器中心旋转 translateX:控制公转半径- 第二层反向
rotate:保证元素自身不旋转,只沿轨道公转
2. 3D 视觉效果
行星光环和小行星带使用 rotateX(75deg),把平面圆环压成倾斜的 3D 环,配合阴影和渐变,瞬间有太空立体感。
3. 性能优化要点
- 用 JS 批量生成元素,避免手动写 1000 个 div
- 动画使用
transform和opacity,触发合成线程,不回流重绘 - 星星大小、动画延迟随机化,减少视觉重复
- 无图片、无字体包,纯代码渲染,加载速度极快
四、项目拓展方向
大家可以基于这个项目继续优化,做出更炫酷的效果:
- 添加鼠标交互:星星跟随鼠标移动、点击生成流星
- 增加更多行星:多行星系统,不同轨道、颜色、转速
- 添加音效:深空白噪音,沉浸式体验拉满
- 适配移动端:调整尺寸,支持手机端全屏展示
- 加入暗黑模式切换、星空亮度调节
五、演示地址
六、总结
这个深空艺术项目,完美展示了CSS 的艺术创作能力和JS 的动态操控能力。不需要复杂的图形库,只用基础前端技术,就能打造出惊艳的视觉效果。
对于前端开发者来说,CSS 艺术不仅能提升对样式、动画、变换的理解,还能激发创作灵感。希望这个项目能给大家带来启发,动手试试吧,用代码画出属于自己的宇宙!