✨ 第十一章:过渡与动画

让网页动起来,提升用户体验

11.1 过渡 (transition)

过渡用于在不同状态之间创建平滑的动画效果。

基本语法

.element {
    transition: property duration timing-function delay;
}

.element {
    transition-property: all;
    transition-duration: 0.3s;
    transition-timing-function: ease;
    transition-delay: 0s;
}

缓动函数

描述
ease 默认,缓入缓出
linear 线性
ease-in 缓入
ease-out 缓出
ease-in-out 缓入缓出
cubic-bezier() 自定义贝塞尔曲线

过渡示例

悬停我
.demo-box {
    width: 100px;
    height: 100px;
    background: #3498db;
    transition: all 0.3s ease;
}

.demo-box:hover {
    transform: scale(1.2) rotate(10deg);
    background: #e74c3c;
}

11.2 关键帧动画 (@keyframes)

关键帧动画用于创建更复杂的动画效果,可以控制动画的各个阶段。

基本语法

@keyframes animation-name {
    0% {
        transform: translateY(0);
    }
    50% {
        transform: translateY(-20px);
    }
    100% {
        transform: translateY(0);
    }
}

.element {
    animation: animation-name 2s infinite;
}

关键帧动画示例

@keyframes bounce {
    0%, 100% {
        transform: translateY(0);
    }
    50% {
        transform: translateY(-20px);
    }
}

.animation-demo {
    animation: bounce 2s infinite;
}

11.3 动画控制

.element {
    animation-name: bounce;
    animation-duration: 2s;
    animation-timing-function: ease;
    animation-delay: 1s;
    animation-iteration-count: infinite;
    animation-direction: alternate;
    animation-fill-mode: both;
    animation-play-state: running;
}

/* 简写形式 */
.element {
    animation: bounce 2s ease 1s infinite alternate both running;
}

11.4 滚动驱动动画

滚动驱动动画是 CSS 中最强大的特性之一,无需 JavaScript 即可实现基于滚动的动画。

基本语法

.element {
    animation: fade-in 1s linear;
    animation-timeline: scroll();
    animation-range: entry 0% cover 50%;
}

@keyframes fade-in {
    0% {
        opacity: 0;
        transform: translateY(20px);
    }
    100% {
        opacity: 1;
        transform: translateY(0);
    }
}

滚动进度条示例

滚动这个区域,观察顶部的进度条...

滚动进度条是使用滚动驱动动画实现的,无需 JavaScript。

继续滚动...

更多内容...

更多内容...

更多内容...

更多内容...

更多内容...

.scroll-indicator {
    width: 0%;
    height: 4px;
    background: #3498db;
    position: fixed;
    top: 0;
    left: 0;
    animation: scroll-progress auto linear;
    animation-timeline: scroll();
}

@keyframes scroll-progress {
    to {
        width: 100%;
    }
}

11.5 性能优化

will-change 属性

告诉浏览器元素即将发生变化,让浏览器提前做好准备。

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

GPU 加速

使用 transform 和 opacity 属性触发 GPU 加速,避免重排。

最佳实践:优先使用 transform 和 opacity 进行动画,因为它们不会触发重排,性能更好。

11.6 减少动画

考虑用户的偏好,为喜欢减少动画的用户提供替代方案。

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

实战案例

悬停效果

.button {
    padding: 10px 20px;
    background: #3498db;
    color: white;
    border-radius: 5px;
    transition: all 0.3s ease;
}

.button:hover {
    transform: translateY(-2px);
    box-shadow: 0 5px 15px rgba(52, 152, 219, 0.4);
}

页面加载动画

.loader {
    width: 48px;
    height: 48px;
    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);
    }
}

动手练习

练习 1:过渡效果

  1. 创建一个卡片元素
  2. 为卡片添加悬停效果,包括缩放、阴影和颜色变化
  3. 调整过渡时间和缓动函数

练习 2:关键帧动画

  1. 创建一个加载动画
  2. 使用 @keyframes 定义动画
  3. 调整动画参数

练习 3:滚动驱动动画

  1. 创建一个元素,当滚动到视图中时淡入
  2. 使用 animation-timeline: scroll()
  3. 调整动画范围