关于 material-design-3-motion
为设计师和开发者提供 Material Design 3 Expressive 动效实施指南,介绍弹簧物理、动效模式、无障碍和实现模式,并附 CSS 动效示例。
主要功能
- 01基于弹簧的动效参数与模式
- 02进入、退出及共享元素转场
- 03微交互、错开动画与形状变换
- 04时长建议及动效令牌
- 05减少动态效果与性能指导
- 06CSS 动效模式示例
适用场景
- 01为按钮和控件添加操作反馈
- 02设计屏幕间转场和容器变换
- 03为列表配置错开出现动画
- 04遵循减少动态效果偏好
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ shelbeely/ shelbeely-agent-skills --skill material-design-3-motion安装后在 Claude Code 中输入/material-design-3-motion确认已加载。
附带文件examples/motion-patterns.css
详细介绍
Material Design 3 动效与动画
概述
本技能指导如何实现 Material Design 3(M3)的表现力动效原则,打造富有弹性、自然流畅的动画,提升易用性并带给用户愉悦体验。
关键词:Material Design 3、M3、动效、动画、过渡、微交互、缓动、时长、弹簧物理、表现力动效、触觉反馈、基于物理的动画
核心原则
表现力动效理念
M3 表现力动效旨在营造鲜活、自然且响应灵敏的体验:
- 基于物理的弹簧:使用由刚度、阻尼和速度控制的弹簧动画,取代传统的三次贝塞尔缓动,让动效更加自然、鲜活
- 有目的的动效:每个动画都应发挥作用——引导注意力、提供反馈或展示关系
- 响应灵敏的体验:动效以适当的速度和时机响应用户输入
- 空间连贯性:元素的移动方式应符合空间关系和物理规律
- 触觉反馈集成:将弹簧动画与平台原生触觉反馈配合使用,增强触感
动效模式
表现力动效(M3 表现力模式的默认选项):
- 产生过冲和弹跳,增添动感
- 适用于触控交互和重点时刻
- 营造活泼且能引发情感共鸣的体验
- 使用更高的弹簧能量和明显的弹跳效果
标准动效(实用型流程):
- 动感克制,弹跳极少
- 更适合注重效率或对系统至关重要的流程
- 自然流畅,不过分活泼
传统动效(兼容性):
- 使用传统缓动以保持向后兼容
- 仅在无法应用弹簧物理时使用
弹簧物理参数
M3 表现力动效使用三个关键物理参数,而非传统的时间/缓动曲线:
- 刚度:控制弹簧的“硬度”——刚度越高,动画完成得越快
- 阻尼:决定弹跳消退的速度——阻尼值为 1 时,弹跳会完全消失
- 初始速度:设定初始速度,影响整体时长和观感
| 方案 | 刚度 | 阻尼 | 弹跳效果 |
|---|---|---|---|
| 表现力 | 高 | 中 | 明显过冲 |
| 标准 | 中 | 高 | 极少/无 |
动画类型
1. 过渡
进入过渡(元素出现):
- 淡入 + 缩放:元素淡入,同时从 80% 缩放至 100%
- 淡入 + 滑动:元素从边缘滑入,同时淡入
- 容器变换:将一个容器变形为另一个容器
退出过渡(元素消失):
- 淡出 + 缩放:元素淡出,同时缩小至 80%
- 淡出 + 滑动:元素滑出
- 退出动画应快于进入动画(保持向前的动势)
共享元素过渡(屏幕/状态之间):
- 在不同视图间平滑变换容器
- 保持视觉连贯性
- 使用容器变换模式
2. 微交互
悬停状态:
- 轻微改变高度(添加阴影)
- 使用状态层改变颜色
- 轻微缩放(1.02x-1.05x)
- 时长:100-200ms
焦点状态:
- 轮廓或环形动画
- 缩放或高度变化
- 时长:200-300ms
按压/触控状态:
- 从触控点扩散的涟漪效果
- 轻微缩小(0.98x)
- 带不透明度的状态层
- 时长:100-150ms
加载状态:
- 闪烁光效或骨架屏
- 圆形进度指示器
- 线性进度条
- 连续、平滑的动效
3. 复杂动画
交错动画:
- 为列表项添加递增延迟后播放动画
- 项目间延迟:30-50ms
- 营造级联效果
编排动画:
- 多个元素协同移动
- 使用 animation-delay 进行编排
- 保持空间关系
形状变形:
- 在不同形状之间平滑插值路径
- 过渡时改变圆角半径
- 用于状态变化和形态变换
时长指南
标准时长
超短(50-100ms):
- 图标状态变化
- 工具提示出现
- 简单的不透明度变化
短(100-200ms):
- 按钮悬停状态
- 简单的缩放动画
- 颜色过渡
中(200-300ms):
- 模态对话框
- 导航过渡
- 卡片展开
长(300-500ms):
- 页面过渡
- 复杂变换
- 面板呈现
超长(500ms+):
- 重大状态变化
- 全屏过渡
- 谨慎使用
根据上下文调整
- 移动设备:稍快(基础时长的 0.8x-0.9x)
- 桌面设备:标准时长
- 减少动态效果:缩短至标准时长的 10-20%,或禁用
- 大型元素:按比例延长时长
弹簧物理实现
表现力弹簧(M3 Expressive 默认)
/* CSS with expressive spring-like bezier approximation */
transition-timing-function: cubic-bezier(0.05, 0.7, 0.1, 1.0);
/* Enhanced linear() for expressive spring with overshoot */
transition-timing-function: linear(
0, 0.004, 0.016 2.5%, 0.063 5%, 0.141, 0.25,
0.391 11.3%, 0.563, 0.765, 1.000 20%, 1.066 23.8%,
1.109 27.5%, 1.130 31.3%, 1.138 35%, 1.136 38.8%,
1.121 46.3%, 1.093 53.8%, 1.057 61.3%, 1.025 68.8%,
1.005 77.5%, 0.997 87.5%, 1
);
标准弹簧
/* CSS with standard spring-like bezier approximation */
transition-timing-function: cubic-bezier(0.2, 0.0, 0, 1.0);
/* CSS linear() for better standard spring approximation */
transition-timing-function: linear(
0, 0.009, 0.035 2.1%, 0.141 4.4%, 0.723 12.9%,
0.938 16.7%, 1.017, 1.077, 1.121, 1.149 24.3%,
1.159, 1.163, 1.161, 1.154 29.9%, 1.129 32.8%,
1.051 39.6%, 1.017 43.1%, 0.991, 0.977 51%,
0.974 53.8%, 0.975 57.1%, 0.997 69.8%, 1.003 76.9%, 1
);
JavaScript(Web Animations API)
// Expressive spring animation
element.animate(
[
{ transform: 'scale(0)', opacity: 0 },
{ transform: 'scale(1)', opacity: 1 }
],
{
duration: 300,
easing: 'cubic-bezier(0.05, 0.7, 0.1, 1.0)',
fill: 'forwards'
}
);
// Standard spring animation
element.animate(
[
{ transform: 'translateY(20px)', opacity: 0 },
{ transform: 'translateY(0)', opacity: 1 }
],
{
duration: 250,
easing: 'cubic-bezier(0.2, 0.0, 0, 1.0)',
fill: 'forwards'
}
);
选择表现力动态效果还是标准动态效果
| 场景 | 动态效果模式 | 原因 |
|---|---|---|
| 按钮按下反馈 | 表现力 | 由用户触发,适合加入弹跳效果 |
| 页面过渡 | 标准 | 功能性效果,不应分散注意力 |
| 加载完成 | 表现力 | 带来愉悦感的庆祝时刻 |
| 表单验证 | 标准 | 实用型反馈 |
| FAB 展开 | 表现力 | 带有视觉强调的关键交互 |
| 列表滚动 | 标准 | 连续动态效果,应保持平滑 |
| 形状变形 | 表现力 | 展现视觉叙事的时刻 |
| 工具提示出现 | 标准 | 提供信息,不应分散注意力 |
触觉反馈集成
M3 Expressive 建议将弹簧驱动的动画与平台原生触觉反馈配合使用:
原则
- 与动态效果协调:触觉效果应在动画的关键时刻触发(例如,过冲或完成时)
- 匹配强度:轻微交互使用轻柔的触觉反馈,重大状态变化则使用更强的反馈
- 采用平台原生方案:使用平台的触觉引擎,以获得最自然的体验
- 尊重用户偏好:遵循用户的触觉设置,并提供无障碍选项
Web 实现
// Pair haptic feedback with expressive motion
function expressivePress(element) {
// Trigger haptic feedback
if (navigator.vibrate) {
navigator.vibrate(10); // Short, subtle haptic
}
// Trigger spring animation
element.animate([
{ transform: 'scale(1)' },
{ transform: 'scale(0.95)' },
{ transform: 'scale(1.02)' },
{ transform: 'scale(1)' }
], {
duration: 300,
easing: 'cubic-bezier(0.05, 0.7, 0.1, 1.0)'
});
}
实现模式
容器变换
在一个容器到另一个容器之间平滑变形:
// Using View Transitions API (modern browsers)
document.startViewTransition(() => {
// Update DOM
container.classList.toggle('expanded');
});
// CSS
::view-transition-old(container),
::view-transition-new(container) {
animation-duration: 300ms;
animation-timing-function: cubic-bezier(0.2, 0.0, 0, 1.0);
}
共轴过渡
元素沿着共用轴退出和进入:
/* X-axis shared transition */
.exit-left {
animation: exit-left 300ms cubic-bezier(0.2, 0.0, 0, 1.0);
}
.enter-right {
animation: enter-right 300ms cubic-bezier(0.2, 0.0, 0, 1.0);
}
@keyframes exit-left {
from { transform: translateX(0); opacity: 1; }
to { transform: translateX(-100px); opacity: 0; }
}
@keyframes enter-right {
from { transform: translateX(100px); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
高度变化
通过阴影和变换为高度添加动画:
.elevated-card {
transition:
box-shadow 200ms cubic-bezier(0.2, 0.0, 0, 1.0),
transform 200ms cubic-bezier(0.2, 0.0, 0, 1.0);
}
.elevated-card:hover {
box-shadow:
0px 4px 8px rgba(0, 0, 0, 0.12),
0px 8px 16px rgba(0, 0, 0, 0.08);
transform: translateY(-2px);
}
波纹效果
用于触摸反馈的 Material 波纹效果:
.ripple {
position: relative;
overflow: hidden;
}
.ripple::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 0;
height: 0;
border-radius: 50%;
background: rgba(255, 255, 255, 0.5);
transform: translate(-50%, -50%);
transition: width 0.3s, height 0.3s;
}
.ripple:active::after {
width: 300%;
height: 300%;
}
最佳实践
应当
- ✅ 使用弹簧物理实现自然动态效果
- ✅ 根据元素大小匹配动画时长(越大越长)
- ✅ 为用户交互提供即时反馈
- ✅ 使用动态效果展示元素之间的关系
- ✅ 在低端设备上测试动画
- ✅ 遵循 prefers-reduced-motion 设置
- ✅ 使用错开动画,让大型数据集显得更轻盈
- ✅ 确保动态效果有明确目的且具备实用性
不应
- ❌ 不要使用线性缓动(感觉机械)
- ❌ 不要同时为过多属性添加动画
- ❌ 不要让动画过慢(感觉迟缓)
- ❌ 不要忽略无障碍偏好设置
- ❌ 不要纯粹为了装饰而使用动态效果
- ❌ 不要过度为布局属性添加动画(会导致重排)
- ❌ 不要随意使用不同的缓动曲线
无障碍
减少动态效果
始终尊重用户偏好:
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
焦点指示器
确保动画焦点状态仍清晰可见:
- 保持足够的对比度
- 不要仅依靠动态效果来指示焦点
- 同时使用颜色和形状变化
性能
- 优先使用
transform和opacity(由 GPU 加速) - 避免为
width、height、top、left添加动画(会导致布局重排) - 对复杂动画谨慎使用
will-change - 在移动设备和低端硬件上进行测试
动态效果令牌
定义动态效果令牌以保持一致性。M3 Expressive 引入了基于弹簧的令牌化动态效果:
:root {
/* Durations */
--md-sys-motion-duration-short1: 50ms;
--md-sys-motion-duration-short2: 100ms;
--md-sys-motion-duration-short3: 150ms;
--md-sys-motion-duration-short4: 200ms;
--md-sys-motion-duration-medium1: 250ms;
--md-sys-motion-duration-medium2: 300ms;
--md-sys-motion-duration-medium3: 350ms;
--md-sys-motion-duration-medium4: 400ms;
--md-sys-motion-duration-long1: 450ms;
--md-sys-motion-duration-long2: 500ms;
--md-sys-motion-duration-long3: 550ms;
--md-sys-motion-duration-long4: 600ms;
/* Easing — Standard (utilitarian) */
--md-sys-motion-easing-standard: cubic-bezier(0.2, 0.0, 0, 1.0);
--md-sys-motion-easing-standard-decelerate: cubic-bezier(0.0, 0.0, 0, 1.0);
--md-sys-motion-easing-standard-accelerate: cubic-bezier(0.3, 0.0, 1.0, 1.0);
/* Easing — Expressive (default for M3 Expressive) */
--md-sys-motion-easing-expressive: cubic-bezier(0.05, 0.7, 0.1, 1.0);
--md-sys-motion-easing-expressive-decelerate: cubic-bezier(0.05, 0.7, 0.1, 1.0);
--md-sys-motion-easing-expressive-accelerate: cubic-bezier(0.3, 0.0, 0.8, 0.15);
/* Easing — Emphasized (legacy naming, same as expressive) */
--md-sys-motion-easing-emphasized: cubic-bezier(0.05, 0.7, 0.1, 1.0);
--md-sys-motion-easing-emphasized-decelerate: cubic-bezier(0.05, 0.7, 0.1, 1.0);
--md-sys-motion-easing-emphasized-accelerate: cubic-bezier(0.3, 0.0, 0.8, 0.15);
/* Legacy easing */
--md-sys-motion-easing-legacy: cubic-bezier(0.4, 0.0, 0.2, 1.0);
/* Expressive tokenized motion (new in M3 Expressive) */
--md-sys-motion-expressive-fast-spatial: cubic-bezier(0.05, 0.7, 0.1, 1.0);
--md-sys-motion-expressive-fast-effects: cubic-bezier(0.2, 0.0, 0, 1.0);
--md-sys-motion-expressive-slow-spatial: cubic-bezier(0.05, 0.7, 0.1, 1.0);
--md-sys-motion-expressive-slow-effects: cubic-bezier(0.2, 0.0, 0, 1.0);
}
动效实现检查清单
实现 M3 动效时,请确保:
- 使用基于弹簧物理的缓动(而非线性或缓入缓出)
- 根据具体情境恰当选择表现力动效或标准动效模式
- 动画时长与元素的大小和复杂程度相匹配
- 尊重减少动态效果的偏好设置
- 尽可能只为变换和不透明度添加动画
- 悬停、焦点和按压状态都有适当的反馈
- 页面过渡流畅连贯
- 动效具有实际功能
- 为列表使用交错动画
- 在移动设备上测试所有动画
- 定义并一致地使用动效令牌(包括表现力令牌)
- 在视图过渡中使用容器变换
- 为触控目标实现涟漪效果
- 在适当情况下,使触觉反馈与弹簧动画协调
- 形状变形动画使用具有表现力的缓动
资源
examples/motion-patterns.css— 可直接使用的 CSS 动画模式,使用 M3 动效令牌(淡入淡出、缩放、滑动、共享轴、状态层、海拔和主题过渡)。将相关的 @keyframes 和类复制到你的项目中。- M3 动效概览:https://m3.material.io/styles/motion/overview
- Material Design 令牌(动效):https://github.com/material-foundation/material-tokens
评论
支持 Markdown