CSS动画是现代网页设计中不可或缺的一部分,它能够为用户界面添加生动的交互效果,提升用户体验。本文将介绍CSS动画的三个主要组成部分:过渡(Transition)、变换(Transform)和动画(Animation)。
一. 过渡(Transition)
过渡允许CSS属性值在指定的时间内平滑地变化,而不是立即变化。这是实现简单动画效果的最基本方式。
基本语法
css
.element {
/* 单个属性过渡 */
transition-property: opacity; /* 指定过渡的CSS属性 */
transition-duration: 0.3s; /* 过渡持续时间 */
transition-timing-function: ease; /* 过渡时间函数 */
transition-delay: 0s; /* 过渡延迟时间 */
/* 简写形式 */
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
,表示没有延迟
实际应用示例
1. 按钮悬停效果
html
<button class="btn">悬停按钮</button>
css
.btn {
padding: 10px 20px;
background-color: #3498db;
color: white;
border: none;
border-radius: 4px;
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);
}
2. 卡片翻转效果
html
<div class="card-container">
<div class="card">
<div class="card-front">正面内容</div>
<div class="card-back">背面内容</div>
</div>
</div>
css
.card-container {
perspective: 1000px;
width: 200px;
height: 300px;
}
.card {
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d;
transition: transform 0.6s;
}
.card-front, .card-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
display: flex;
align-items: center;
justify-content: center;
border-radius: 10px;
}
.card-front {
background-color: #f1c40f;
}
.card-back {
background-color: #e74c3c;
transform: rotateY(180deg);
}
.card-container:hover .card {
transform: rotateY(180deg);
}
3. 导航菜单下划线效果
html
<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>
css
.menu {
display: flex;
list-style: none;
gap: 20px;
}
.menu a {
text-decoration: none;
color: #333;
position: relative;
padding: 5px 0;
}
.menu a::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 2px;
background-color: #3498db;
transition: width 0.3s ease;
}
.menu a:hover::after {
width: 100%;
}
二. 变换(Transform)
变换允许你修改元素的形状、大小和位置,而不影响文档流。它通常与过渡或动画结合使用,创建更复杂的视觉效果。
2D变换
css
.element {
/* 平移 */
transform: translateX(20px); /* 水平方向平移 */
transform: translateY(20px); /* 垂直方向平移 */
transform: translate(20px, 20px); /* 水平和垂直方向平移 */
/* 缩放 */
transform: scaleX(1.5); /* 水平方向缩放 */
transform: scaleY(1.5); /* 垂直方向缩放 */
transform: scale(1.5); /* 水平和垂直方向等比例缩放 */
transform: scale(1.5, 0.5); /* 水平和垂直方向不等比例缩放 */
/* 旋转 */
transform: rotate(45deg); /* 顺时针旋转45度 */
transform: rotate(-45deg); /* 逆时针旋转45度 */
/* 倾斜 */
transform: skewX(15deg); /* 水平方向倾斜 */
transform: skewY(15deg); /* 垂直方向倾斜 */
transform: skew(15deg, 10deg); /* 水平和垂直方向倾斜 */
/* 组合变换 */
transform: translate(20px, 20px) rotate(45deg) scale(1.5);
/* 注意:变换的顺序会影响最终结果 */
}
3D变换
css
.element {
/* 3D平移 */
transform: translateZ(20px); /* Z轴平移 */
transform: translate3d(20px, 20px, 20px); /* X、Y、Z轴平移 */
/* 3D旋转 */
transform: rotateX(45deg); /* 绕X轴旋转 */
transform: rotateY(45deg); /* 绕Y轴旋转 */
transform: rotateZ(45deg); /* 绕Z轴旋转,等同于rotate(45deg) */
transform: rotate3d(1, 1, 1, 45deg); /* 绕自定义轴旋转 */
/* 3D缩放 */
transform: scaleZ(1.5); /* Z轴缩放 */
transform: scale3d(1.5, 1.5, 1.5); /* X、Y、Z轴缩放 */
/* 透视 */
transform: perspective(500px); /* 设置透视距离 */
}
/* 3D变换相关属性 */
.container {
perspective: 1000px; /* 设置观察者与z=0平面的距离 */
perspective-origin: center center; /* 设置透视的观察点位置 */
}
.element {
transform-style: preserve-3d; /* 子元素保留3D空间 */
backface-visibility: hidden; /* 隐藏元素的背面 */
}
变换原点
css
.element {
transform-origin: center center; /* 默认值,变换的原点在元素中心 */
transform-origin: top left; /* 变换的原点在元素左上角 */
transform-origin: 50px 50px; /* 变换的原点在距离左上角50px, 50px的位置 */
transform-origin: 50% 50% 0; /* 3D变换的原点 */
}
实际应用示例
1. 图片悬停放大效果
html
<div class="image-container">
<img src="image.jpg" alt="示例图片">
</div>
css
.image-container {
width: 300px;
height: 200px;
overflow: hidden;
border-radius: 8px;
}
.image-container img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.5s ease;
}
.image-container:hover img {
transform: scale(1.1);
}
2. 3D卡片效果
html
<div class="card-3d">
<div class="card-content">
<div class="card-front">正面内容</div>
<div class="card-back">背面内容</div>
</div>
</div>
css
.card-3d {
perspective: 1000px;
width: 200px;
height: 300px;
}
.card-content {
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d;
transition: transform 0.8s;
}
.card-front, .card-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
display: flex;
align-items: center;
justify-content: center;
border-radius: 10px;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
.card-front {
background-color: #3498db;
color: white;
}
.card-back {
background-color: #2ecc71;
color: white;
transform: rotateY(180deg);
}
.card-3d:hover .card-content {
transform: rotateY(180deg);
}
3. 按钮点击效果
html
<button class="btn-3d">3D按钮</button>
css
.btn-3d {
position: relative;
padding: 12px 24px;
background-color: #e74c3c;
color: white;
border: none;
border-radius: 5px;
font-weight: bold;
cursor: pointer;
transform-style: preserve-3d;
transform: translateZ(0);
transition: transform 0.2s, box-shadow 0.2s;
box-shadow: 0 6px 0 #c0392b, 0 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)
关键帧定义了动画在特定时间点的样式。
css
@keyframes slidein {
from {
transform: translateX(100%);
opacity: 0;
}
50% {
opacity: 0.5;
}
to {
transform: translateX(0);
opacity: 1;
}
}
动画属性
css
.element {
/* 指定动画名称 */
animation-name: slidein;
/* 指定动画持续时间 */
animation-duration: 1s;
/* 指定动画的速度曲线 */
animation-timing-function: ease;
/* 指定动画开始前的延迟时间 */
animation-delay: 0s;
/* 指定动画的播放次数 */
animation-iteration-count: 1; /* 具体数值或infinite(无限循环) */
/* 指定动画的播放方向 */
animation-direction: normal;
/* 其他值: reverse(反向), alternate(交替), alternate-reverse(反向交替) */
/* 指定动画的填充模式 */
animation-fill-mode: none;
/* 其他值: forwards(保持最后一帧), backwards(应用第一帧), both(同时应用) */
/* 指定动画的运行状态 */
animation-play-state: running; /* 或paused(暂停) */
/* 简写形式 */
animation: slidein 1s ease 0s 1 normal forwards running;
/* 多个动画 */
animation: slidein 1s ease, fadeout 2s ease 1s;
}
实际应用示例
1. 加载动画
html
<div class="loader"></div>
css
.loader {
width: 50px;
height: 50px;
border: 5px solid #f3f3f3;
border-top: 5px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
2. 脉冲效果
html
<div class="pulse"></div>
css
.pulse {
width: 100px;
height: 100px;
background-color: #3498db;
border-radius: 50%;
position: relative;
animation: pulse 2s ease infinite;
}
@keyframes pulse {
0% {
transform: scale(0.95);
box-shadow: 0 0 0 0 rgba(52, 152, 219, 0.7);
}
70% {
transform: scale(1);
box-shadow: 0 0 0 15px rgba(52, 152, 219, 0);
}
100% {
transform: scale(0.95);
box-shadow: 0 0 0 0 rgba(52, 152, 219, 0);
}
}
3. 弹跳文本
html
<div class="bouncing-text">
<span>B</span>
<span>O</span>
<span>U</span>
<span>N</span>
<span>C</span>
<span>E</span>
</div>
css
.bouncing-text {
display: flex;
justify-content: center;
align-items: center;
}
.bouncing-text span {
font-size: 2rem;
font-weight: bold;
color: #3498db;
display: inline-block;
animation: bounce 0.5s ease infinite alternate;
}
.bouncing-text span:nth-child(2) {
animation-delay: 0.1s;
}
.bouncing-text span:nth-child(3) {
animation-delay: 0.2s;
}
.bouncing-text span:nth-child(4) {
animation-delay: 0.3s;
}
.bouncing-text span:nth-child(5) {
animation-delay: 0.4s;
}
.bouncing-text span:nth-child(6) {
animation-delay: 0.5s;
}
@keyframes bounce {
0% {
transform: translateY(0);
}
100% {
transform: translateY(-15px);
}
}
4. 淡入淡出轮播图
html
<div class="slideshow">
<div class="slide"></div>
<div class="slide"></div>
<div class="slide"></div>
</div>
css
.slideshow {
position: relative;
width: 100%;
height: 300px;
overflow: hidden;
}
.slide {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
background-size: cover;
background-position: center;
animation: slideshow 15s infinite;
}
.slide:nth-child(1) {
background-image: url('image1.jpg');
animation-delay: 0s;
}
.slide:nth-child(2) {
background-image: url('image2.jpg');
animation-delay: 5s;
}
.slide:nth-child(3) {
background-image: url('image3.jpg');
animation-delay: 10s;
}
@keyframes slideshow {
0%, 25%, 100% {
opacity: 0;
z-index: 0;
}
30%, 45% {
opacity: 1;
z-index: 1;
}
50%, 95% {
opacity: 0;
z-index: 0;
}
}
四. 性能优化
高性能动画
为了创建流畅的动画,应该优先考虑以下属性,因为它们可以由GPU加速:
transform
opacity
filter
尽量避免直接修改影响布局的属性,如:
width
/height
margin
/padding
top
/left
/right
/bottom
font-size
其他优化技巧
- 使用
will-change
属性
css
.element {
will-change: transform, opacity;
}
- 使用
requestAnimationFrame
进行JavaScript动画
javascript
function animate() {
// 更新动画
element.style.transform = `translateX(${position}px)`;
// 请求下一帧
requestAnimationFrame(animate);
}
// 开始动画
requestAnimationFrame(animate);
-
减少同时运行的动画数量
-
使用
transform: translateZ(0)
或transform: translate3d(0,0,0)
触发GPU加速
css
.element {
transform: translateZ(0);
}
五. 响应式动画
基于媒体查询的动画调整
css
@media (max-width: 768px) {
.element {
animation-duration: 0.5s; /* 在小屏幕上使用更短的动画时间 */
}
}
@media (prefers-reduced-motion: reduce) {
.element {
animation: none; /* 对于那些偏好减少动画的用户,禁用动画 */
transition: none;
}
}
使用CSS变量控制动画
css
:root {
--animation-duration: 1s;
--animation-distance: 20px;
}
@media (max-width: 768px) {
:root {
--animation-duration: 0.5s;
--animation-distance: 10px;
}
}
.element {
animation: slide var(--animation-duration) ease;
}
@keyframes slide {
from {
transform: translateX(var(--animation-distance));
}
to {
transform: translateX(0);
}
}
总结
CSS动画是创建交互式和吸引人的网页界面的强大工具:
- 过渡(Transition) 适用于简单的状态变化,如悬停效果。
- 变换(Transform) 提供了改变元素形状、大小和位置的能力,不影响文档流。
- 动画(Animation) 允许创建复杂的多状态动画序列,可以自动播放。