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 のエクスプレッシブなモーションは、生き生きとして自然で、応答性の高い感触になるよう設計されています。
- 物理ベースのスプリング: 剛性、減衰、速度によって制御されるスプリングベースのアニメーションを使用します。より自然で生き生きとした動きにするため、従来の cubic-bezier イージングに置き換えます。
- 目的のあるモーション: すべてのアニメーションには、注意を引く、フィードバックを提供する、関係性を示すなどの目的が必要です。
- 応答性の高い感触: モーションは、適切な速度とタイミングでユーザー入力に応答します。
- 空間的な一貫性: 要素は、空間的な関係性と物理法則を尊重する形で移動します。
- 触覚フィードバックとの統合: スプリングアニメーションとプラットフォーム標準の触覚フィードバックを組み合わせ、触覚による補強を行います。
モーションモード
エクスプレッシブモーション(M3 Expressive のデフォルト):
- オーバーシュートやバウンスを加え、動きに活力を与えます。
- タッチ操作や印象的な場面に適しています。
- 遊び心があり、感情に響く感触を生み出します。
- スプリングのエネルギーを高め、はっきりとしたバウンスを使用します。
標準モーション(実用的なフロー):
- 控えめで、バウンスを最小限にします。
- 生産性重視やシステム上重要なフローに適しています。
- 過度な遊び心を抑えながら、自然な感触を保ちます。
レガシーモーション(互換性):
- 下位互換性のために従来のイージングを使用します。
- スプリングの物理特性を適用できない場合にのみ使用します。
スプリングの物理パラメーター
M3 のエクスプレッシブなモーションでは、従来の時間/イージング曲線の代わりに、次の3つの主要な物理パラメーターを使用します。
- 剛性: スプリングの「硬さ」を制御します。剛性が高いほど、アニメーションはより速く終了します。
- 減衰: バウンスがどれほど速く収まるかを決定します。減衰値が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.8~0.9倍)
- デスクトップ:標準的な時間
- 動きを減らす設定:標準時間の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 モーションを実装する際は、以下を確認してください。
- 線形や ease-in-out ではなく、スプリングベースの物理演算によるイージングを使用している
- コンテキストに応じて、エクスプレッシブと標準のモーションモードを適切に選択している
- 要素のサイズと複雑さに合わせたデュレーションを設定している
- モーション低減の設定を尊重している
- 可能な場合は、transform と opacity のみをアニメーションさせている
- ホバー、フォーカス、押下状態に適切なフィードバックがある
- ページ遷移が滑らかで一貫している
- モーションに機能上の目的がある
- リストにスタガーアニメーションを使用している
- すべてのアニメーションをモバイルデバイスでテストしている
- モーショントークンが定義され、一貫して使用されている(エクスプレッシブトークンを含む)
- ビュー遷移にコンテナ変換を使用している
- タッチターゲットにリップル効果を実装している
- 適切な場合は、触覚フィードバックをスプリングアニメーションと連携させている
- シェイプモーフィングアニメーションにエクスプレッシブイージングを使用している
リソース
examples/motion-patterns.css— M3 モーショントークンを使用した、すぐに使える CSS アニメーションパターン(フェード、スケール、スライド、共有軸、状態レイヤー、エレベーション、テーマ遷移)。関連する @keyframes とクラスをプロジェクトにコピーしてください。- M3 モーションの概要:https://m3.material.io/styles/motion/overview
- Material Design Tokens(モーション):https://github.com/material-foundation/material-tokens