跳转到内容

4.1 CSS 过渡

CSS 过渡(Transitions)是创建平滑状态变化的最简单方法。本节将详细介绍如何使用过渡效果来增强用户界面的交互体验。


一、过渡基础

1.1 什么是过渡

过渡是指元素从一种状态平滑过渡到另一种状态的效果。当某个属性的值发生变化时,过渡会自动在两者之间进行插值,产生平滑的动画效果。

1.2 何时使用过渡

适合使用过渡的场景:

  • 按钮悬停效果
  • 菜单展开/收起
  • 颜色变化
  • 大小和位置调整
  • 不透明度变化

不适合使用过渡的场景:

  • 复杂的多步骤动画
  • 需要精确控制的动画
  • 循环动画(使用关键帧动画)

二、过渡属性

2.1 transition

简写属性,用于一次性设置所有过渡相关的属性。

css
/* 语法 */
transition: property duration timing-function delay;

/* 示例 */
.button {
    transition: all 0.3s ease-out;
}

/* 多个属性 */
.button {
    transition: 
        background-color 0.3s ease-out,
        transform 0.2s cubic-out,
        opacity 0.4s linear;
}

2.2 transition-property

指定哪些属性应该应用过渡效果。

css
/* 单个属性 */
.button {
    transition-property: background-color;
}

/* 多个属性 */
.button {
    transition-property: background-color, transform, opacity;
}

/* 所有属性 */
.button {
    transition-property: all;
}

/* 没有属性 */
.button {
    transition-property: none;
}

2.3 transition-duration

指定过渡动画的持续时间。

css
.button {
    transition-duration: 0.3s;  /* 300ms */
}

.button {
    transition-duration: 500ms;  /* 500ms */
}

/* 不同属性使用不同时长 */
.button {
    transition-duration: 
        background-color 0.3s,
        transform 0.2s,
        opacity 0.4s;
}

2.4 transition-timing-function

指定过渡动画的时间函数(缓动效果)。

css
/* 预设缓动函数 */
.button {
    transition-timing-function: ease;        /* 默认 */
}

.button {
    transition-timing-function: linear;      /* 线性 */
}

.button {
    transition-timing-function: ease-in;     /* 慢速开始 */
}

.button {
    transition-timing-function: ease-out;    /* 慢速结束 */
}

.button {
    transition-timing-function: ease-in-out; /* 慢速开始和结束 */
}

/* 自定义缓动函数 */
.button {
    transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}

/* 特殊缓动函数 */
.button {
    transition-timing-function: quadratic-in;
}

.button {
    transition-timing-function: cubic-in;
}

.button {
    transition-timing-function: quartic-out;
}

.button {
    transition-timing-function: exponential-in-out;
}

.button {
    transition-timing-function: elastic-out;
}

.button {
    transition-timing-function: bounce-out;
}

常用缓动函数对比

函数特点适用场景
ease默认,平滑通用过渡
linear匀速进度条、加载动画
ease-out快速开始,慢速结束按钮悬停、滑块
ease-in-out慢速开始和结束页面切换、淡入淡出
cubic-bezier自定义曲线需要精确控制时
elastic-out弹性效果强调反馈
bounce-out弹跳效果通知提示

2.5 transition-delay

指定过渡动画的延迟时间。

css
.button {
    transition-delay: 0s;    /* 立即开始 */
}

.button {
    transition-delay: 0.5s;  /* 延迟 500ms */
}

.button {
    transition-delay: 1s;    /* 延迟 1s */
}

三、实际应用示例

3.1 按钮悬停效果

css
/* 基础按钮样式 */
.button {
    padding: 10px 20px;
    background: #3498db;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    
    /* 过渡设置 */
    transition: 
        background-color 0.3s ease-out,
        transform 0.2s cubic-out,
        box-shadow 0.3s ease-out;
}

/* 悬停状态 */
.button:hover {
    background: #2980b9;
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}

/* 点击状态 */
.button:active {
    transform: translateY(0);
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}

/* 禁用状态 */
.button:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

3.2 菜单展开/收起

css
/* 菜单项 */
.menu-item {
    height: 40px;
    opacity: 1;
    overflow: hidden;
    transition: 
        height 0.3s ease-out,
        opacity 0.3s ease-out;
}

/* 隐藏状态 */
.menu-item.collapsed {
    height: 0;
    opacity: 0;
}
xml
<div class="menu">
    <div class="menu-item">项目 1</div>
    <div class="menu-item collapsed">项目 2</div>
    <div class="menu-item collapsed">项目 3</div>
</div>

3.3 卡片翻转效果

css
.card {
    width: 200px;
    height: 300px;
    perspective: 1000px;
    cursor: pointer;
}

.card-inner {
    width: 100%;
    height: 100%;
    position: relative;
    transition: transform 0.6s cubic-out;
    transform-style: preserve-3d;
}

.card:hover .card-inner {
    transform: rotateY(180deg);
}

.card-front, .card-back {
    position: absolute;
    width: 100%;
    height: 100%;
    backface-visibility: hidden;
    border-radius: 8px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}

.card-front {
    background: white;
}

.card-back {
    background: #3498db;
    color: white;
    transform: rotateY(180deg);
}

3.4 进度条动画

css
.progress-bar {
    width: 200px;
    height: 20px;
    background: #e0e0e0;
    border-radius: 3px;
    overflow: hidden;
}

.progress-fill {
    height: 100%;
    width: 0%;
    background: linear-gradient(to right, #3498db, #2ecc71);
    transition: width 0.5s cubic-out;
}

/* 加载时的脉冲效果 */
.progress-bar.loading .progress-fill {
    width: 100%;
    transition: width 2s linear;
}

3.5 模态框淡入淡出

css
.modal-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.5);
    opacity: 0;
    visibility: hidden;
    transition: 
        opacity 0.3s ease-out,
        visibility 0.3s ease-out;
}

.modal-overlay.visible {
    opacity: 1;
    visibility: visible;
}

.modal {
    width: 400px;
    max-width: 90%;
    background: white;
    border-radius: 8px;
    transform: scale(0.9) translateY(-20px);
    transition: 
        transform 0.3s cubic-out,
        opacity 0.3s ease-out;
    opacity: 0;
}

.modal-overlay.visible .modal {
    transform: scale(1) translateY(0);
    opacity: 1;
}

四、性能优化

4.1 使用 GPU 加速

某些属性会触发 GPU 加速,提高性能:

css
/* 好的属性(GPU 加速) */
.element {
    transition: 
        transform 0.3s ease-out,
        opacity 0.3s ease-out;
}

/* 避免(CPU 渲染) */
.element {
    transition: 
        width 0.3s ease-out,
        height 0.3s ease-out,
        top 0.3s ease-out,
        left 0.3s ease-out;
}

4.2 减少过渡属性

只对必要的属性应用过渡:

css
/* 不好的做法 */
.element {
    transition: all 0.3s ease-out;
}

/* 好的做法 */
.element {
    transition: 
        transform 0.3s ease-out,
        opacity 0.3s ease-out;
}

4.3 使用 will-change 提示

对于复杂动画,可以使用 will-change 提示浏览器:

css
.animated-element {
    will-change: transform, opacity;
    transition: 
        transform 0.3s ease-out,
        opacity 0.3s ease-out;
}

注意:谨慎使用 will-change,只在需要时使用。


五、高级技巧

5.1 延迟交错动画

css
/* 菜单项 */
.menu-item {
    opacity: 0;
    transform: translateX(-20px);
    transition: 
        opacity 0.3s ease-out,
        transform 0.3s ease-out;
}

/* 显示状态 */
.menu-item.visible {
    opacity: 1;
    transform: translateX(0);
}

/* 交错延迟 */
.menu-item:nth-child(1) { transition-delay: 0.0s; }
.menu-item:nth-child(2) { transition-delay: 0.1s; }
.menu-item:nth-child(3) { transition-delay: 0.2s; }
.menu-item:nth-child(4) { transition-delay: 0.3s; }

5.2 条件过渡

css
/* 根据父元素状态应用过渡 */
.parent:hover .child {
    transform: scale(1.1);
}

.child {
    transition: transform 0.3s ease-out;
}

5.3 过渡与类切换

css
/* 定义过渡 */
.box {
    width: 100px;
    height: 100px;
    background: #3498db;
    transition: 
        width 0.5s cubic-out,
        background-color 0.3s ease-out;
}

/* 扩展状态 */
.box.expanded {
    width: 200px;
    background: #2ecc71;
}
xml
<!-- 切换类 -->
<div class="box" onclick="toggle_class()"></div>
cpp
// C++ 代码:切换类
void toggle_class() {
    auto element = document->GetElementById("box");
    if (element->IsClassSet("expanded")) {
        element->RemoveClass("expanded");
    } else {
        element->SetClass("expanded", true);
    }
}

六、常见问题

6.1 过渡不生效

问题:属性变化时没有过渡效果。

原因

  1. 没有设置 transition 属性
  2. 属性不支持过渡(如 display
  3. 过渡属性和变化属性不匹配

解决方案

css
/* 检查过渡设置 */
.element {
    transition: all 0.3s ease-out;  /* 确保设置了过渡 */
}

/* display 不支持过渡,使用其他方式 */
.element {
    opacity: 0;
    visibility: hidden;
    transition: 
        opacity 0.3s ease-out,
        visibility 0.3s ease-out;
}

.element.visible {
    opacity: 1;
    visibility: visible;
}

6.2 过渡性能问题

问题:动画卡顿或掉帧。

解决方案

css
/* 使用 GPU 加速的属性 */
.element {
    transition: 
        transform 0.3s ease-out,
        opacity 0.3s ease-out;
}

/* 避免频繁触发布局重排 */
.element {
    transition: transform 0.3s ease-out;  /* 好 */
    /* transition: width 0.3s ease-out;  差 */
}

6.3 过渡时间不一致

问题:多个属性过渡时间不同步。

解决方案

css
/* 为相关属性设置相同的过渡时间 */
.button {
    transition: 
        background-color 0.3s ease-out,
        transform 0.3s ease-out,
        box-shadow 0.3s ease-out;
}

七、实战练习

练习 1:创建交互式按钮

创建一个具有以下效果的按钮:

  • 悬停时改变颜色和阴影
  • 点击时有缩放效果
  • 禁用状态有透明度变化

练习 2:实现下拉菜单

实现一个带有平滑过渡的下拉菜单:

  • 菜单项展开时有高度和透明度过渡
  • 使用交错延迟使菜单项依次出现

练习 3:设计加载指示器

创建一个加载指示器:

  • 进度条填充时有平滑过渡
  • 完成时有淡出效果

练习 4:制作卡片翻转效果

创建一个可以翻转的卡片:

  • 悬停时翻转 180 度
  • 正面和背面有不同的内容
  • 使用 3D 变换

八、下一步

继续学习 关键帧动画 来创建更复杂的动画效果。


📝 检查清单

基于 MIT 许可发布