不用 JavaScript,你能用 CSS 做到什么?答案:拍一部星战电影!

前言:当代码遇上原力

"愿原力与你同在。"

------ 但今天,原力不在绝地武士手中,而在你的键盘里。

你有没有想过,不用一滴墨水、一台摄影机,甚至一行 JavaScript,就能复刻《星球大战》那令人血脉偾张的经典片头?那个字幕如银河般倾斜滚动,从遥远星系缓缓驶来的史诗感------它不是特效大片,而是纯 CSS3 的魔法杰作!

是的,你没看错。前端工程师,就是这个时代的数字导演 。我们用 HTML 搭建宇宙舞台,用 CSS 调度光影与运动,用 transform 驱动原力,用 animation 编写命运。这一次,我们不写页面,我们拍电影。

准备好了吗?光剑已亮,引擎启动------让我们用代码,开启一场穿越星河的视觉远征。


项目结构

首先我们要创建一个项目,项目结构如图所示

bg.jpg

由于此处无法上传svg格式的图片,所以我把gitee的链接放上来,大家可以通过链接获取图片

star.svg

css/starwars/img/star.svg · Zou/lesson_zp - 码云 - 开源中国

wars.svg

css/starwars/img/wars.svg · Zou/lesson_zp - 码云 - 开源中国


index.html:搭建舞台

xml 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>html5&css3 星球大战</title>
  <link rel="stylesheet" href="./style.css">
</head>
<body>
  <div class="starwars">
    <img src="./img/star.svg" alt="star" class="star">
    <img src="./img/wars.svg" alt="wars" class="wars">
    <h2 class="byline" id="byline">
        <!-- span*13 -->
      <span>T</span>
      <span>h</span>
      <span>e</span>
      <span>F</span>
      <span>o</span>
      <span>r</span>
      <span>c</span>
      <span>e</span>
      <span>A</span>
      <span>w</span>
      <span>a</span>
      <span>k</span>
      <span>e</span>
    </h2>
  </div>
</body>
</html>
  • <div class="starwars"> 是整个动画的容器。
  • .byline 显示引导语,语义上使用 <p><h2> 更合适,但这里用 div 简化。
  • .star.wars 是两张图片,分别代表"STAR"和"WARS"。

style.css源码

css 复制代码
/*
  标准 CSS Reset
  基于 Eric Meyer 的 Reset 并结合现代浏览器特性
*/

/* 所有元素应用 border-box 模型,方便布局 */
*,
*::before,
*::after {
  box-sizing: border-box;
}

/* 重置所有元素的内外边距、边框、字体等 */
html,
body,
div,
span,
applet,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
hgroup,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline;
}

/* HTML5 语义化元素设为块级 */
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
  display: block;
}

/* 重置列表样式 */
ol,
ul {
  list-style: none;
}

/* 重置表格样式 */
table {
  border-collapse: collapse;
  border-spacing: 0;
}

/* 重置图片、视频等替换元素 */
img,
video,
canvas,
audio,
svg {
  display: block;
  max-width: 100%;
}

/* 重置表单元素 */
button,
input,
select,
textarea {
  /* 继承字体和颜色 */
  font: inherit;
  color: inherit;
  /* 移除默认边框和轮廓 */
  border: none;
  outline: none;
  /* 清除默认样式 */
  background: transparent;
  /* 统一垂直对齐 */
  vertical-align: middle;
}

/* 链接重置 */
a {
  text-decoration: none;
  color: inherit; /* 继承父元素颜色 */
}

/* 防止字体缩放 */
body {
  line-height: 1;
  -webkit-text-size-adjust: 100%;
}

/* 清除浮动(可选) */

.clearfix::after {
  content: "";
  display: table;
  clear: both;
}

/* 业务代码 */
body {
  height: 100vh;
  background: url(./img/bg.jpg);
}

.starwars {
  /* 
  相对单位,相对于自身的字体大小
  默认字体大小 16px
  1em = 16px
  34em = 544px
  17em = 272px
  */
  width: 34em;
  height: 17em;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  /* 透视距离,模拟3D效果 */
  perspective: 800px;
  /* 子元素保持3D效果 */
  transform-style: preserve-3d;
}

img {
  width: 100%;
}

.star,
.wars,
.byline {
  position: absolute;
}

.star {
  top: -0.75em;
  /* 动画属性:star 10秒 缓出 无限循环 */
  animation:star 10s ease-out infinite;
}

.wars {
  bottom: -0.5em;
  animation:wars 10s ease-out infinite;
}

.byline {
  left:-2em;
  right:-2em;
  top:45%;
  text-align:center;
  text-transform:uppercase;
  letter-spacing:0.4em;
  font-size:1.6em;
  color:#fff;
  animation:move-byline 10s linear infinite;
}

.byline span {
  display: inline-block;
  animation:spin-letter 10s linear infinite;
}

/* 设计动作 动画的关键帧 */
@keyframes star {
  /* 每个关键帧写上属性 */
  0% {
    opacity: 0;
    transform:scale(1.5) translateY(-0.75em);
  }
  20% {
    opacity: 1;
  }
  89%{
    opacity:1;
    transform:scale(1);
  }
  100%{
    opacity:0;
    transform:translateZ(-1000em);
  }
}


@keyframes wars {
  0% {
    opacity: 0;
    transform:scale(1.5) translateY(0.5em);
  }
  20% {
    opacity: 1;
  }
  90%{
    opacity:1;
    transform:scale(1);
  }
  100%{
    opacity:0;
    transform:translateZ(-1000em);
  }
}

@keyframes move-byline {
  0% {
    transform:translateZ(25em);
  }
  100% {
    transform:translateZ(0);
  }
}

@keyframes spin-letter {
  0%, 10%{
    opacity:0;
    transform:rotateY(90deg) translateZ(20px); /*添加Z轴位移增强3D效果*/
  }
  30%{
    opacity:1;
    transform:rotateY(0) translateZ(0);
  }
  70%,86%{
    transform:rotateY(0) translateZ(0);
    opacity:1;
  }
  95%{
    opacity:0;
  }
}

CSS 属性详解:导演的镜头语言

下面我们从业务代码处开始逐行解析关键 CSS 属性,理解它们如何协同工作,创造出电影级效果。

css 复制代码
/* 业务代码 */
body {
  height: 100vh;
  background: url(./img/bg.jpg);
}

.starwars {
  /* 
  相对单位,相对于自身的字体大小
  默认字体大小 16px
  1em = 16px
  34em = 544px
  17em = 272px
  */
  width: 34em;
  height: 17em;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  /* 透视距离,模拟3D效果 */
  perspective: 800px;
  /* 子元素保持3D效果 */
  transform-style: preserve-3d;
}

img {
  width: 100%;
}

.star,
.wars,
.byline {
  position: absolute;
}

.star {
  top: -0.75em;
  /* 动画属性:star 10秒 缓出 无限循环 */
  animation:star 10s ease-out infinite;
}

.wars {
  bottom: -0.5em;
  animation:wars 10s ease-out infinite;
}

.byline {
  left:-2em;
  right:-2em;
  top:45%;
  text-align:center;
  text-transform:uppercase;
  letter-spacing:0.4em;
  font-size:1.6em;
  color:#fff;
  animation:move-byline 10s linear infinite;
}

.byline span {
  display: inline-block;
  animation:spin-letter 10s linear infinite;
}
CSS 选择器 属性 说明
body height: 100vh 视口高度的 100%,确保背景填满整个屏幕。
background: url(./img/bg.jpg) 设置星空背景图,营造宇宙氛围。
.starwars position: absolute 脱离文档流,进行绝对定位。
top: 50%; left: 50% 将元素左上角定位到页面中心。
transform: translate(-50%, -50%) 元素自身向左上移动 50%,实现精准水平垂直居中。
perspective: 800px 设置 3D 透视距离,值越小透视感越强(类似镜头拉近)。
transform-style: preserve-3d 保持子元素的 3D 空间效果,避免被"压平"。
.star, .wars, .byline position: absolute 所有文字/图片元素绝对定位,便于在 3D 空间自由控制位置。
.star top: -0.75em 将"STAR"图像向上偏移 0.75em,微调垂直位置,避免与引导语重叠。
animation: star 10s ease-out infinite 启用 star 动画,持续 10 秒,缓出效果,无限循环播放。
.wars bottom: -0.5em 将"WARS"图像向下偏移 0.5em,精确控制其在容器中的底部位置。
animation: wars 10s ease-out infinite 启用 wars 动画,持续 10 秒,缓出效果,无限循环播放。
.byline animation: move-byline 10s linear infinite 调用 move-byline 动画,持续 10 秒,匀速播放,无限循环。
text-transform: uppercase 文字全部大写,符合电影标题风格。
letter-spacing: 0.4em 增加字母间距,增强科技感与视觉呼吸感。
color: #fff 白色文字,与深色背景形成高对比度,更醒目。
.byline span animation: spin-letter 10s linear infinite 每个字符独立执行 spin-letter 动画,实现逐字旋转入场效果。

动画关键帧解析:时间轴上的表演

@keyframes star

css 复制代码
@keyframes star {
  0% {
    opacity: 0;
    transform: scale(1.5) translateY(-0.75em);
  }
  20% { opacity: 1; }
  89% { transform: scale(1); }
  100% { 
    opacity: 0; 
    transform: translateZ(-1000em); 
  }
}
百分比 属性 说明
0% opacity: 0; transform:scale(1.5) translateY(-0.75em); 开始时透明,尺寸放大1.5倍,并向上移动0.75em。
20% opacity: 1; 逐渐变得完全不透明。
89% opacity:1; transform:scale(1); 保持不透明状态,恢复原始大小。
100% opacity:0; transform:translateZ(-1000em); 最终透明并沿Z轴向后移动,产生远离效果。

@keyframes wars

css 复制代码
@keyframes wars {
  0% {
    opacity: 0;
    transform:scale(1.5) translateY(0.5em);
  }
  20% {
    opacity: 1;
  }
  90%{
    opacity:1;
    transform:scale(1);
  }
  100%{
    opacity:0;
    transform:translateZ(-1000em);
  }
}
百分比 属性 说明
0% opacity: 0; transform:scale(1.5) translateY(0.5em); 开始时透明,尺寸放大1.5倍,并向下移动0.5em。
20% opacity: 1; 逐渐变得完全不透明。
90% opacity:1; transform:scale(1); 保持不透明状态,恢复原始大小。
100% opacity:0; transform:translateZ(-1000em); 最终透明并沿Z轴向后移动,产生远离效果。
  • 从透明、放大、偏移开始,逐渐显现。
  • 最后向 Z 轴深处飞去,消失在宇宙尽头,制造"远去"感。

@keyframes move-byline

css 复制代码
@keyframes move-byline {
  0% { transform: translateZ(25em); }
  100% { transform: translateZ(0); }
}
百分比 属性 说明
0% transform:translateZ(25em); 初始位置沿Z轴向前移动25em。
100% transform:translateZ(0); 结束位置回到原点,即Z轴上无位移。
  • 引导语从远处(Z 轴 25em)向前移动,仿佛从宇宙深处缓缓靠近观众。

@keyframes spin-letter

css 复制代码
@keyframes spin-letter {
  0%, 10%{
    opacity:0;
    transform:rotateY(90deg) translateZ(20px); /*添加Z轴位移增强3D效果*/
  }
  30%{
    opacity:1;
    transform:rotateY(0) translateZ(0);
  }
  70%,86%{
    transform:rotateY(0) translateZ(0);
    opacity:1;
  }
  95%{
    opacity:0;
  }
}
百分比 属性 说明
0%, 10% opacity:0; transform:rotateY(90deg) translateZ(20px); 开始和早期阶段透明,字符绕Y轴旋转90度并向Z轴前方移动20px。
30% opacity:1; transform:rotateY(0) translateZ(0); 变为完全不透明且旋转回初始位置。
70%,86% transform:rotateY(0) translateZ(0); opacity:1; 继续保持在原始位置且不透明。
95% opacity:0; 最终阶段变为透明。
  • 每个字母从 Y 轴旋转 90 度(侧面对着你),并带 Z 轴位移,实现立体翻转入场。
  • 逐步显现,增强动态层次感。

总结:前端即导演,代码即镜头

技术 作用
transform 实现 3D 位移、旋转、缩放,构建空间感。
animation + @keyframes 控制动效节奏,定义视觉叙事时间轴。
perspective 模拟摄像机视角,增强景深效果。
translate(-50%, -50%) 实现元素精准居中,布局核心技巧。
transform-style: preserve-3d 维持 3D 空间层级,避免子元素塌陷。
translateZ() 控制元素前后移动,制造"驶向/远离"视觉。
rotateY() 实现字符翻转入场,增强动态层次。

结语:你的浏览器,就是银河系

"You don't need the Force to move mountains. You just need transform: translateZ();."

这场没有 JavaScript 的"电影",证明了 CSS3 的力量早已超越"样式表"的范畴。它是一门视觉语言 ,一种表达方式 ,更是前端工程师手中的光剑

下一次,当你面对一个平淡的页面时,不妨问自己:

"这段代码,能拍出一部电影吗?"

因为在这个时代,每一行 CSS,都是通往银河的传送门。

🌌 愿原力(与 CSS)与你同在。

相关推荐
地方地方3 小时前
event loop 事件循环
前端·javascript·面试
golang学习记3 小时前
从0死磕全栈之在 Next.js 中使用 Sass
前端
好大的月亮3 小时前
oss中的文件替换后chrome依旧下载到缓存文件概述
前端·chrome·缓存
Broken Arrows3 小时前
解决Jenkins在构建前端任务时报错error minimatch@10.0.3:……的记录
运维·前端·jenkins
明月与玄武3 小时前
JS 自定义事件:从 CustomEvent 到 dispatchEvent!
前端·javascript·vue.js
Zhencode3 小时前
vue之异步更新队列
前端·javascript·vue.js
九年义务漏网鲨鱼4 小时前
从零学习 Agentic RL(四)—— 超越 ReAct 的线性束缚:深入解析 Tree-of-Thoughts (ToT)
前端·学习·react.js
Jay丶4 小时前
Next.js 与 SEO:让搜索引擎爱上你的网站 💘
前端·javascript·react.js
狗头大军之江苏分军4 小时前
请不要在感情里丢掉你的“我”
前端·后端