Transitions.dev は何をしますか?
12 個の移植可能な CSS トランジション。それぞれ t-* セレクタとセマンティックな CSS カスタムプロパティで名前空間化されています。スニペットを貼り付け、ドキュメント化された HTML フックを接続するだけです。フレームワークの依存関係は不要で、デモ固有のマークアップもなく、すべてのスニペットには prefers-reduced-motion ガードが含まれています。
クイックリファレンス
| トランジション | 使用タイミング | リファレンス |
|---|---|---|
| カードリサイズ | コンテナのレイアウト状態が変化したときに、幅または高さをトゥイーンします。 | 01-card-resize.md |
| 数字ポップイン | 数字が更新されたときに、ぼかしスライドを伴って各数字を再表示します。 | 02-number-pop-in.md |
| 通知バッジ | トリガー上に小さなバッジをスライドさせ、ドットをポップ表示します。 | 03-notification-badge.md |
| テキスト状態差し替え | ぼかしを伴う上下のトランジションでテキストをその場で差し替えます。 | 04-text-states-swap.md |
| メニュードロップダウン | トリガーから成長する、原点を考慮したドロップダウンを開きます。 | 05-menu-dropdown.md |
| モーダル開閉 | モーダルダイアログをスケールアップし、閉じるときはよりソフトなスケールダウンを行います。 | 06-modal.md |
| パネル表示 | クロスぼかしを伴ってパネルを領域にスライドインします。 | 07-panel-reveal.md |
| ページ横並び | 2つの横並びページ間をスライドします(リスト↔詳細、ステップ1↔ステップ2)。 | 08-page-side-by-side.md |
| アイコン差し替え | ぼかしとスケールを伴って、同じスロット内の2つのアイコンをクロスフェードします。 | 09-icon-swap.md |
| 成功チェック | フェード+回転+Y方向ボブ+パスストローク描画を合成し、アクション完了を演出します。 | 10-success-check.md |
| アバターグループホバー | アイテム列を距離減衰で浮き上がらせ、戻るときにバネのような弾みをつけます。 | 11-avatar-group-hover.md |
| エラー状態シェイク | 区間ごとに3次ベジェ曲線でシェイクし、ボーダーとメッセージを自動的に元に戻します。 | 12-error-state-shake.md |
決定ルール
ユーザーがトランジションを要求した場合、最初に可視の UI 要素、次に動詞と照合します。
- トリガー+上部に浮かぶ小さなドット → 通知バッジ。
- トリガー+そこから成長するサーフェス → ドロップダウン(アンカー付き、原点対応)またはモーダル(中央揃え、アンカーなし)。
- ページの領域にスライドインするサーフェス → パネル表示。
- 2つの画面、リスト↔詳細 または ステップ1↔ステップ2 → ページ横並び。
- 要素の幅または高さが変化する → カードリサイズ。
- 要素のテキストコンテンツがその場で変化する → テキスト状態差し替え。
- 同じスロット内の2つのアイコン → アイコン差し替え。
- 数字が更新される → 数字ポップイン。
- 確認/成功/'完了'の瞬間(チェックマーク、支払い処理済み、ファイルアップロード完了) → 成功チェック。
- 水平スタック内のアイテムをホバー(アバター、チップ、セグメントボタン、タグピル) → アバターグループホバー。
- フォーム検証エラー/'これは間違っている'というフィードバック(無効なフィールド、間違ったPIN、重複した名前) → エラー状態シェイク。
- 明確な一致なし →
transitions revealにフォールバックし、ユーザーに選択させます。推測しないでください。
2つのトランジションが適合する可能性がある場合は、オーバーヘッドが少ない方を優先します(パネル表示よりカードリサイズ、モーダルよりドロップダウン、フルモーダル演出より成功チェック)。ただし、デザインが明らかに重いサーフェスを必要とする場合はこの限りではありません。成功チェックはアニメーションのみです。スピナーからチェックへの切り替えも必要な場合は、アイコン差し替えと組み合わせてください。
コマンド
このスキルは、直接のトランジション要求に加えて、エージェントが認識すべき3つの名前空間化された動詞を公開します。すべてのコマンドは transitions で始まるため、同じプロジェクトにインストールされている他のスキルの動詞と競合することはありません。
transitions reveal — すべてのトランジションを一覧表示
トリガーフレーズ: transitions reveal, "トランジションを表示", "すべてのトランジションを一覧表示", "このスキルのトランジションは?", "トランジションカタログを表示"。
動作: 12個のトランジションを番号付きプレーンテキストリスト(名前、1行概要、該当リファレンスファイル名)で出力します。上記の ## クイックリファレンス の行を再利用し、新しいコピーを作成しないでください。プロジェクトへのアクセスは不要です。
transitions review — プロジェクトを監査して適合性を確認
トリガーフレーズ: transitions review, "プロジェクトをレビュー", "アニメーションを監査", "どこで transitions.dev が役立つか", "このスキルを使う場所を探す"。
動作:
- ワークスペースで次の指標を検索:
transition:宣言、@keyframes、スタイルファイル内のハードコードされたms/sの長さ、11個の決定ルールパターン(モーダル、ドロップダウン、バッジなど)に一致するコンポーネント。 - ヒットごとに決定ルールと照合し、最適なトランジションを1つ選択します。
- ファイルごとにグループ化された番号付きリストを出力:
path/to/Component.tsx:L42— ドロップダウンのように見えるため、menu-dropdown (05-menu-dropdown.md) を提案。- すでに
t-*クラスを使用しているアドホックなトランジションはスキップします。
- 何も編集しないでください。「
transitions applyを任意の行に対して実行すると、提案されたトランジションをインストールできます。」で終了します。
transitions apply — 最適なトランジションをインストール
トリガーフレーズ: transitions apply, "ここにトランジションを適用", "適切なトランジションを追加", "transitions-dev をここにインストール", "この要素のアニメーションを修正"。
動作:
- コンテキストを読み取る: 現在開いているファイル、カーソルに最も近い要素、周囲の CSS / JSX。ユーザーが明示的にトランジションを指定した場合(例:
transitions apply menu-dropdown)、それを使用します。 - そのコンテキストに対して
## 決定ルールのルールを実行し、1つのトランジションを選択します。2つ適合する可能性がある場合は、オーバーヘッドが少ない方を優先します(既存のルールと同じタイブレーカー)。 - 1行の提案を表示: 「ここでは menu-dropdown を適用します。要素がトリガーから開き、アンカーが付いているためです。インストールしますか?」
- 確認後、
## 出力形式の既存の5ステップ手順(ルートブロック、スニペット、フック、reduced-motion ガード、必要に応じて JS オーケストレーション)に従います。 - エージェントが確信を持って1つのトランジションを選択できない場合は、
transitions revealにフォールバックし、ユーザーに選択を促します。
ユニバーサルインストール
この :root ブロックをプロジェクトに1回ドロップします。すべてのトランジションスニペットはこれらのセマンティック名から読み取ります。後で追跡する必要のあるコンポーネントごとの値はありません。
/* transitions-dev — この :root ブロックをプロジェクトに一度コピーしてください。
すべてのトランジションスニペットはこれらのセマンティック名から読み取ります。 */
:root {
/* カードリサイズ */
--resize-dur: 300ms;
--resize-ease: cubic-bezier(0.22, 1, 0.36, 1);
/* 数字ポップイン */
--digit-dur: 500ms;
--digit-distance: 8px;
--digit-stagger: 70ms;
--digit-blur: 2px;
--digit-ease: cubic-bezier(0.34, 1.45, 0.64, 1);
--digit-dir-x: 0;
--digit-dir-y: 1;
/* 通知バッジ */
--badge-slide-dur: 260ms;
--badge-pop-dur: 500ms;
--badge-pop-close-dur: 180ms;
--badge-fade-dur: 400ms;
--badge-fade-close-dur: 180ms;
--badge-blur: 2px;
--badge-offset-x: -8.2px;
--badge-offset-y: 12.4px;
--badge-slide-ease: cubic-bezier(0.22, 1, 0.36, 1);
--badge-pop-ease: cubic-bezier(0.34, 1.36, 0.64, 1);
--badge-close-ease: cubic-bezier(0.4, 0, 0.2, 1);
/* テキスト状態差し替え */
--text-swap-dur: 150ms;
--text-swap-translate-y: 4px;
--text-swap-blur: 2px;
--text-swap-ease: ease-in-out;
/* メニュードロップダウン */
--dropdown-open-dur: 250ms;
--dropdown-close-dur: 150ms;
--dropdown-pre-scale: 0.97;
--dropdown-closing-scale: 0.99;
--dropdown-ease: cubic-bezier(0.22, 1, 0.36, 1);
/* モーダル開閉 */
--modal-open-dur: 250ms;
--modal-close-dur: 150ms;
--modal-scale: 0.96;
--modal-scale-close: 0.96;
--modal-ease: cubic-bezier(0.22, 1, 0.36, 1);
/* パネル表示 */
--panel-open-dur: 400ms;
--panel-close-dur: 350ms;
--panel-translate-y: 100px;
--panel-blur: 2px;
--panel-ease: cubic-bezier(0.22, 1, 0.36, 1);
/* ページ横並び */
--page-slide-dur: 200ms;
--page-fade-dur: 200ms;
--page-slide-distance: 8px;
--page-blur: 3px;
--page-stagger: 0ms;
--page-exit-enabled: 1;
--page-slide-ease: cubic-bezier(0.22, 1, 0.36, 1);
--page-fade-ease: cubic-bezier(0.22, 1, 0.36, 1);
/* アイコン差し替え */
--icon-swap-dur: 200ms;
--icon-swap-blur: 2px;
--icon-swap-start-scale: 0.25;
--icon-swap-ease: ease-in-out;
/* 成功チェック */
--check-opacity-dur: 550ms;
--check-rotate-dur: 550ms;
--check-rotate-from: 80deg;
--check-bob-dur: 450ms;
--check-y-amount: 40px;
--check-blur-dur: 500ms;
--check-blur-from: 10px;
--check-path-dur: 550ms;
--check-path-delay: 80ms;
--check-ease-out: cubic-bezier(0.22, 1, 0.36, 1);
--check-ease-opacity: cubic-bezier(0.22, 1, 0.36, 1);
--check-ease-rotate: cubic-bezier(0.22, 1, 0.36, 1);
--check-ease-bob: cubic-bezier(0.34, 1.35, 0.64, 1);
--check-ease-path: cubic-bezier(0.22, 1, 0.36, 1);
/* アバターグループホバー */
--avatar-lift: -4px;
--avatar-dur: 320ms;
--avatar-scale: 1.05;
--avatar-falloff: 0.45;
--avatar-ease-in: cubic-bezier(0.22, 1, 0.36, 1);
--avatar-ease-out: cubic-bezier(0.34, 3.85, 0.64, 1);
/* エラー状態シェイク */
--shake-distance: 6px;
--shake-overshoot: 4px;
--shake-dur-a: 80ms;
--shake-dur-b: 60ms;
--shake-ease: cubic-bezier(0.22, 1, 0.36, 1);
--revert-hold: 3000ms;
--revert-dur: 280ms;
}
ライブデモ transitions.dev で使用されている --pX-* ソーストークンは、ここでは意図的にエクスポートしていません。調整可能な値はセマンティック名 (--badge-*, --dropdown-*, --modal-*, …) に名前変更されているため、ユーザーがデザインの語彙を所有できます。
出力形式
ユーザーのプロジェクトにトランジションを挿入する場合:
- 上記の
:rootブロックをユーザーのグローバルスタイルシートに追加しますが、まだ存在しない場合のみです。ユーザーがすでにユニバーサルインストールブロックを一度インポートしている場合は、重複させないでください。 - 選択したトランジションのCSSを該当リファレンスファイルからそのまま貼り付けます。セレクタを書き換えたり、トランジションをショートハンドに圧縮したり、
will-changeを削除したりしないでください。スニペットは調整済みでテスト済みです。 - ドキュメント化されたHTMLフック(クラス名:
.t-dropdown,.t-modal,.t-success-check,.t-avatar,.t-input, …)および状態属性(data-open,data-state,data-page,.is-open,.is-closing,.is-exit,.is-enter-start,.is-animating,.is-error,.is-shaking)を接続します。 @media (prefers-reduced-motion: reduce)ブロックを維持します。 すべてのスニペットに含まれています。これを削除すると、アクセシビリティ監査に不合格になります。- JSが必要なトランジション(ドロップダウン、モーダル、テキスト差し替え、数字ポップイン、ページスライド、成功チェック、アバターグループホバー、エラー状態シェイク)については、リファレンスファイルから小さなオーケストレーションスニペットをコピーし、セレクタをユーザーのDOMに適合させます。タイミングの読み取り(
getComputedStyle(...)getPropertyValue("--…"))を維持し、:rootの値と同期するようにします。
差分は小さく保ってください。トランジションの導入に必要なファイルのみを編集します。ユーザーの既存の変数の名前を変更したり、無関係なCSSを再フォーマットしたり、モーションライブラリを取り込んだりしないでください。
避けるべき一般的な間違い
- ドロップダウン/モーダルのクローズ状態クラスのクリーンアップを削除すること —
.is-closingを削除するsetTimeoutがないと、次のオープンが静止したオープン前のスケールではなく、クローズ中のスケールから開始されます。 - テキスト差し替え、数字ポップイン、成功チェックの再再生、エラー状態シェイクでのリフローを忘れること — クラス/属性の削除と再追加の間に
void el.offsetWidth(またはoffsetHeight)を実行することが、アニメーションの再再生を保証します。 - 内部のピースではなく単一のコンテナをアニメーションすること — バッジの場合はドットをアニメーションし、トリガーはアニメーションしません。ページスライドの場合は、コンテナではなくページセクションをアニメーションします。
transition: …をtransition: allに置き換えること — すべてのスニペットは意図的に正確なプロパティを列挙しており、無関係なスタイル変更が無料で適用されないようにしています。- 成功チェックの
stroke-dasharrayをハードコードすること — スニペットはプレースホルダーとして20を出荷します。ご自身のパスについては、path.getTotalLength()を1切り上げた値に置き換えてください。そうしないと、ストロークが事前に表示されたり、過剰に描画されたりします。 - アバターグループホバーの
transition-timing-functionをCSSで設定すること —--shift/--scale-activeの書き込み前にJSでインライン設定する必要があります。そうすることで、バネのようなイーズアウトがmouseleave時にのみ適用されます。 - エラー状態シェイクで
.is-errorと.is-shakingを1つのクラスに混在させること — これらを直交させておくことで、シェイクの再再生(削除→リフロー→再追加)がエラー全体の処理をちらつかせることなく可能になります。
リファレンスファイル
- 01-card-resize.md — カードリサイズ
- 02-number-pop-in.md — 数字ポップイン
- 03-notification-badge.md — 通知バッジ
- 04-text-states-swap.md — テキスト状態差し替え
- 05-menu-dropdown.md — メニュードロップダウン
- 06-modal.md — モーダル開閉
- 07-panel-reveal.md — パネル表示
- 08-page-side-by-side.md — ページ横並び
- 09-icon-swap.md — アイコン差し替え
- 10-success-check.md — 成功チェック
- 11-avatar-group-hover.md — アバターグループホバー
- 12-error-state-shake.md — エラー状態シェイク
- _root.css — ユニバーサルインストールブロック単体。直接インポートする準備ができています。