Vanson's Eternal Blog

CSS动画

Css basic.png
Published on
/10 mins read/---

CSS动画

过渡(Transition)

过渡允许CSS属性值在指定的时间内平滑地变化,而不是立即变化。这是实现简单动画效果的最基本方式。

基本语法

.element {
  /* 单个属性过渡 */
  transition-property: opacity; /* 指定过渡的CSS属性 */
  transition-duration0.3s/* 过渡持续时间 */
  transition-timing-function: ease/* 过渡时间函数 */
  transition-delay0s/* 过渡延迟时间 */
 
  /* 简写形式 */
  transition: opacity 0.3s ease 0s;
 
  /* 多个属性过渡 */
  transition: opacity 0.3s ease, transform 0.5s ease-in-out;
}

过渡属性

transition-property

  • 指定应用过渡效果的CSS属性名称
  • 值:none、all或特定CSS属性名称(如opacity、transform等)
  • 可以指定多个属性,用逗号分隔

transition-duration

  • 指定过渡效果持续的时间
  • 值:以秒(s)或毫秒(ms)为单位的时间值
  • 默认值为0s,表示没有过渡效果

transition-timing-function

  • 指定过渡效果的速度曲线
  • 常用值:
    • ease:默认值,慢开始,快中间,慢结束
    • linear:匀速
    • ease-in:慢开始,快结束
    • ease-out:快开始,慢结束
    • ease-in-out:慢开始,慢结束
    • cubic-bezier(n,n,n,n):自定义贝塞尔曲线
    • steps(n, start|end):阶梯函数

transition-delay

  • 指定过渡效果开始前的延迟时间
  • 值:以秒(s)或毫秒(ms)为单位的时间值
  • 默认值为0s,表示没有延迟

实际应用示例

按钮悬停效果

<button class="btn">悬停按钮</button>
.btn {
  padding10px20px;
  background-color#3498db;
  color: white;
  border: none;
  border-radius4px;
  cursor: pointer;
  transition: background-color 0.3s ease, transform 0.2s ease;
}
 
.btn:hover {
  background-color#2980b9;
  transform: scale(1.05);
}
 
.btn:active {
  transform: scale(0.95);
}
 

卡片翻转效果

<div class="card-container">
  <div class="card">
    <div class="card-front">正面内容</div>
    <div class="card-back">背面内容</div>
  </div>
</div>
.card-container {
  perspective1000px;
  width200px;
  height300px;
}
 
.card {
  width100%;
  height100%;
  position: relative;
  transform-style: preserve-3d;
  transition: transform 0.6s;
}
 
.card-front.card-back {
  position: absolute;
  width100%;
  height100%;
  backface-visibility: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius10px;
}
 
.card-front {
  background-color#f1c40f;
}
 
.card-back {
  background-color#e74c3c;
  transformrotateY(180deg);
}
 
.card-container:hover .card {
  transformrotateY(180deg);
}
 

导航菜单下划线效果

<nav>
  <ul class="menu">
    <li><a href="#">首页</a></li>
    <li><a href="#">关于</a></li>
    <li><a href="#">服务</a></li>
    <li><a href="#">联系</a></li>
  </ul>
</nav>
.menu {
  display: flex;
  list-style: none;
  gap20px;
}
 
.menua {
  text-decoration: none;
  color#333;
  position: relative;
  padding5px0;
}
 
.menua::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  width: 0;
  height: 2px;
  background-color#3498db;
transition: width 0.3s ease;
}
 
.menua:hover::after {
  width: 100%;
}
 

变换(Transform)

变换允许你修改元素的形状、大小和位置,而不影响文档流。它通常与过渡或动画结合使用,创建更复杂的视觉效果。

2D变换

.element {
  /* 平移 */
  transformtranslateX(20px); /* 水平方向平移 */
  transformtranslateY(20px); /* 垂直方向平移 */
  transformtranslate(20px20px); /* 水平和垂直方向平移 */
 
  /* 缩放 */
  transformscaleX(1.5); /* 水平方向缩放 */
  transformscaleY(1.5); /* 垂直方向缩放 */
  transformscale(1.5); /* 水平和垂直方向等比例缩放 */
  transformscale(1.50.5); /* 水平和垂直方向不等比例缩放 */
 
  /* 旋转 */
  transformrotate(45deg); /* 顺时针旋转45度 */
  transformrotate(-45deg); /* 逆时针旋转45度 */
 
  /* 倾斜 */
  transformskewX(15deg); /* 水平方向倾斜 */
  transformskewY(15deg); /* 垂直方向倾斜 */
  transformskew(15deg10deg); /* 水平和垂直方向倾斜 */
 
  /* 组合变换 */
  transformtranslate(20px20pxrotate(45degscale(1.5);
  /* 注意:变换的顺序会影响最终结果 */
}
 

3D变换

.element {
  /* 3D平移 */
  transformtranslateZ(20px); /* Z轴平移 */
  transformtranslate3d(20px20px20px); /* X、Y、Z轴平移 */
 
  /* 3D旋转 */
  transformrotateX(45deg); /* 绕X轴旋转 */
  transformrotateY(45deg); /* 绕Y轴旋转 */
  transformrotateZ(45deg); /* 绕Z轴旋转,等同于rotate(45deg) */
  transformrotate3d(11145deg); /* 绕自定义轴旋转 */
 
  /* 3D缩放 */
  transformscaleZ(1.5); /* Z轴缩放 */
  transformscale3d(1.51.51.5); /* X、Y、Z轴缩放 */
 
  /* 透视 */
  transformperspective(500px); /* 设置透视距离 */
  }
 
  /* 3D变换相关属性 */
  .container {
  perspective1000px/* 设置观察者与z=0平面的距离 */
  perspective-origin: center center/* 设置透视的观察点位置 */
  }
 
  .element {
  transform-style: preserve-3d/* 子元素保留3D空间 */
  backface-visibility: hidden/* 隐藏元素的背面 */
}
 

变换原点

.element {
  transform-origin: center center/* 默认值,变换的原点在元素中心 */
  transform-origin: top left/* 变换的原点在元素左上角 */
  transform-origin50px 50px/* 变换的原点在距离左上角50px, 50px的位置 */
  transform-origin50% 50% 0/* 3D变换的原点 */
}
 

实际应用示例

图片悬停放大效果

<div class="image-container">
  <img src="image.jpg" alt="示例图片">
</div>
.image-container {
  width300px;
  height200px;
  overflow: hidden;
  border-radius8px;
}
 
.image-containerimg {
  width100%;
  height100%;
  object-fit: cover;
  transition: transform 0.5s ease;
}
 
.image-container:hoverimg {
  transform: scale(1.1);
}
 

3D卡片效果

<div class="card-3d">
  <div class="card-content">
    <div class="card-front">正面内容</div>
    <div class="card-back">背面内容</div>
  </div>
</div>
.card-3d {
  perspective1000px;
  width200px;
  height300px;
}
 
.card-content {
  width100%;
  height100%;
  position: relative;
  transform-style: preserve-3d;
  transition: transform 0.8s;
}
 
.card-front.card-back {
  position: absolute;
  width100%;
  height100%;
  backface-visibility: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius10px;
  box-shadow0 4px 8px rgba(0,0,0,0.1);
}
 
.card-front {
  background-color#3498db;
  color: white;
}
 
.card-back {
  background-color#2ecc71;
  color: white;
  transformrotateY(180deg);
}
 
.card-3d:hover.card-content {
  transformrotateY(180deg);
}
 

按钮点击效果

<button class="btn-3d">3D按钮</button>
.btn-3d {
  position: relative;
  padding12px 24px;
  background-color#e74c3c;
  color: white;
  border: none;
  border-radius5px;
  font-weight: bold;
  cursor: pointer;
  transform-style: preserve-3d;
  transformtranslateZ(0);
  transition: transform 0.2s, box-shadow 0.2s;
  box-shadow0 6px 0 #c0392b0 8px 10px rgba(0,0,0,0.3);
}
 
.btn-3d:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 0 #c0392b, 0 10px 15px rgba(0,0,0,0.3);
}
 
.btn-3d:active {
  transform: translateY(4px);
  box-shadow: 0 2px 0 #c0392b, 0 4px 6px rgba(0,0,0,0.3);
}
 

动画(Animation)

动画允许你创建从一个CSS样式配置到另一个CSS样式配置的过渡效果。与过渡不同,动画可以包含多个状态变化,并且可以自动播放,而不需要触发事件。

关键帧(@keyframes)

关键帧定义了动画在特定时间点的样式。

动画属性

@keyframes slidein {
from {
    transformtranslateX(100%);
    opacity0;
  }
 
50% {
    opacity0.5;
  }
 
to {
    transformtranslateX(0);
    opacity1;
  }
}

实际应用示例

.element {
  /* 指定动画名称 */
  animation-name: slidein;
 
  /* 指定动画持续时间 */
  animation-duration1s;
 
  /* 指定动画的速度曲线 */
  animation-timing-function: ease;
 
  /* 指定动画开始前的延迟时间 */
  animation-delay0s;
 
  /* 指定动画的播放次数 */
  animation-iteration-count1/* 具体数值或infinite(无限循环) */
 
  /* 指定动画的播放方向 */
  animation-direction: normal
  /* 其他值: reverse(反向), alternate(交替), alternate-reverse(反向交替) */
 
  /* 指定动画的填充模式 */
  animation-fill-mode: none;
  /* 其他值: forwards(保持最后一帧), backwards(应用第一帧), both(同时应用) */
 
  /* 指定动画的运行状态 */
  animation-play-state: running/* 或paused(暂停) */
 
  /* 简写形式 */
  animation: slidein 1s ease 0s1 normal forwards running;
 
  /* 多个动画 */
  animation: slidein 1s ease, fadeout 2s ease 1s;
}

加载动画

 
<div class="loader"></div>
.loader {
  width50px;
  height50px;
  border5px solid #f3f3f3;
  border-top5px solid #3498db;
  border-radius50%;
  animation: spin 1s linear infinite;
}
 
@keyframes spin {
  0% { transformrotate(0deg); }
  100% { transformrotate(360deg); }
}

脉冲效果

 
<div class="pulse"></div>
.pulse {
  width100px;
  height100px;
  background-color#3498db;
  border-radius50%;
  position: relative;
  animation: pulse 2s ease infinite;
}
 
@keyframes pulse {
0% {
    transformscale(0.95);
    box-shadow0000rgba(521522190.7);
  }
 
70% {
    transformscale(1);
    box-shadow00015pxrgba(521522190);
  }
 
100% {
    transformscale(0.95);
    box-shadow0000rgba(521522190);
  }
}

弹跳文本

<div class="bouncing-text">
  <span>B</span>
  <span>O</span>
  <span>U</span>
  <span>N</span>
  <span>C</span>
  <span>E</span>
</div>
 
.bouncing-text {
  display: flex;
  justify-content: center;
  align-items: center;
}
 
.bouncing-textspan {
  font-size2rem;
  font-weight: bold;
  color#3498db;
  display: inline-block;
  animation: bounce 0.5s ease infinite alternate;
}
 
.bouncing-textspan:nth-child(2) {
  animation-delay0.1s;
}
 
.bouncing-textspan:nth-child(3) {
  animation-delay0.2s;
}
 
.bouncing-textspan:nth-child(4) {
  animation-delay0.3s;
}
 
.bouncing-textspan:nth-child(5) {
  animation-delay0.4s;
}
 
.bouncing-textspan:nth-child(6) {
  animation-delay0.5s;
}
 
@keyframes bounce {
0% {
    transformtranslateY(0);
  }
100% {
    transformtranslateY(-15px);
  }
}

淡入淡出轮播图

<div class="slideshow">
  <div class="slide"></div>
  <div class="slide"></div>
  <div class="slide"></div>
</div>
 
.slideshow {
  position: relative;
  width100%;
  height300px;
  overflow: hidden;
}
 
.slide {
  position: absolute;
  top0;
  left0;
  width100%;
  height100%;
  opacity0;
  background-size: cover;
  background-position: center;
  animation: slideshow 15s infinite;
}
 
.slide:nth-child(1) {
  background-imageurl('image1.jpg');
  animation-delay0s;
}
 
.slide:nth-child(2) {
  background-imageurl('image2.jpg');
  animation-delay5s;
}
 
.slide:nth-child(3) {
  background-imageurl('image3.jpg');
  animation-delay10s;
}
 
@keyframes slideshow {
0%25%100% {
    opacity0;
    z-index0;
  }
30%45% {
    opacity1;
    z-index1;
  }
50%95% {
    opacity0;
    z-index0;
  }
}

性能优化

高性能动画

为了创建流畅的动画,应该优先考虑以下属性,因为它们可以由GPU加速:

  • transform
  • opacity
  • filter

尽量避免直接修改影响布局的属性,如:

  • width/height
  • margin/padding
  • top/left/right/bottom
  • font-size

其他优化技巧

使用will-change属性

.element {
  will-change: transform, opacity;
}

requestAnimationFrame

使用requestAnimationFrame进行JavaScript动画

function animate() {
  // 更新动画
  element.style.transform = `translateX(${position}px)`;
  
  // 请求下一帧
  requestAnimationFrame(animate);
}
 
// 开始动画
requestAnimationFrame(animate);
 

 减少同时运行的动画数量

transform

使用transform: translateZ(0)或transform: translate3d(0,0,0)触发GPU加速

.element {
  transformtranslateZ(0);
}

响应式动画

基于媒体查询的动画调整

@media (max-width768px) {
  .element {
    animation-duration0.5s/* 在小屏幕上使用更短的动画时间 */
  }
}
 
@media (prefers-reduced-motion: reduce) {
  .element {
    animation: none/* 对于那些偏好减少动画的用户,禁用动画 */
    transition: none;
  }
}

使用CSS变量控制动画

:root {
  --animation-duration: 1s;
  --animation-distance: 20px;
}
 
@media (max-width768px) {
:root {
    --animation-duration: 0.5s;
    --animation-distance: 10px;
  }
}
 
.element {
  animation: slide var(--animation-duration) ease;
}
 
@keyframes slide {
  from {
      transformtranslateX(var(--animation-distance));
    }
  to {
      transformtranslateX(0);
    }
}

总结

CSS动画是创建交互式和吸引人的网页界面的强大工具:

  1. 过渡(Transition) 适用于简单的状态变化,如悬停效果。
  2. 变换(Transform) 提供了改变元素形状、大小和位置的能力,不影响文档流。
  3. 动画(Animation) 允许创建复杂的多状态动画序列,可以自动播放。
← Previous postCSS盒模型
Next post →CSS高级特性