モーションフィール(Motion feels)
ほとんどの人はイージングカーブの名前を知りませんが、物の動き方の「感触」は正確にわかっています:穏やか、パンチが効いている、高級感がある、遊び心がある。これらの言葉は無数のカーブに当てはまるため、AIが推測することになり、「速すぎる」「バウンドを減らして」というラウンドが繰り返されます。このスキルは、あなたと相手に共通の名前のセットを提供し、それぞれに正確な値を紐付けます。相手は感覚で話し、あなたは数値を扱います。
このスキルはウェブサイト向けに書かれています:マーケティングサイト、ポートフォリオ、コンテンツサイト、ショップサイト。アプリやプロダクトUIでも同じフィールが使えます。その場合は各速度の速い方を使用してください。
3つのパート:
- フィール(感覚):どのように動くか。 速度とイージングカーブの組み合わせ。14のフィールは以下にあります。
- エフェクト:何が動くか。 マスクリビール、パララックス、マーキーなど。
references/feels.mdを参照してください。 - ダイヤル フィールを調整する:速度、停止、オーバーシュート、スターガー、距離、遅延、トリガー、強度。
感覚で話し、カーブでは話さない
相手はモーション用語を知らないかもしれませんし、知る必要もありません。
- イージング、カーブ、ベジェ、ミリ秒数を選ばせないでください。 日常生活の例を交えて、感触について尋ねてください:「ゆっくり優しく着地させるべきですか、それともスプリングのように少しオーバーシュートしてから収まるべきですか?」
- フィールの説明は、どのように作られるかではなく、どのように見えるかで行ってください:「速く始まって滑らかに止まる」であり、「power4.out」ではありません。
- フィール名はオプションのショートカットです。 会話の中で軽く言及し(「このフィールを Luxurious(高級感) と呼びます」)、相手が再利用できるようにします。決して必須にせず、相手の言葉を訂正しないでください。
- 数値はコードに入れます。さらに、それをもとにビルドまたはレビューする人向けに短い行を1つ追加します:「開発者向け:1.2 秒、
cubic-bezier(0.22, 1, 0.36, 1)」。誰もそれをもとにビルドしない場合(例えば、相手が方向性を選んでいるだけの場合)、その行は省略してください。 - このファイル内の言葉はあなた向けであり、相手向けではありません。 ダイヤル名やCSS用語はあなたの返信に含めないでください。「最後の小さなバウンド」(オーバーシュート)、「次々と」(スターガー)、「どれだけ動くか」(距離)、「どれだけ優雅に止まるか」(停止)、「同時にどれだけ動くか」(強度)、「どこから成長するか」(起点)、「アニメーションをオフにしている人のために」(動きの抑制)と言い換えてください。
- 1行で翻訳したら、すぐにビルドします。 講釈は不要で、作業を止めてはいけません。唯一の例外は、以下の表で「ask」とマークされている単語で、その場合は最初に1つだけ平易な質問をします。
- 説明より見せること。 相手が言葉にできない場合は、デモページ(
assets/feels-demo.html、任意のブラウザで開けます)を提供するか、簡単なA/Bトグルを作成して選んでもらってください。
14のフィール
| フィール(感覚) | 見た目 | 速度 | CSS | GSAP |
|---|---|---|---|---|
| Crisp(キビキビ) | 電気のスイッチ:瞬間的で、きれいに止まる | 150 ms | cubic-bezier(0.33, 1, 0.68, 1) | power2.out |
| Snappy(パッと) | 飛び出して、しっかりと着地する | 300 ms | cubic-bezier(0.16, 1, 0.3, 1) | expo.out |
| Springy(バネのように) | 素早く、小さなオーバーシュート、その後収まる | 600 ms | spring, bounce 0.3(CSSではlinear()) | スプリングなし。最も近いのは back.out(1.2) |
| Smooth(滑らか) | 引き戸:柔らかく始まり、柔らかく止まる | 500 ms | cubic-bezier(0.65, 0, 0.35, 1) | power2.inOut |
| Gentle(優しい) | 漂うように現れて、フェードアウトしながら止まる | 700 ms | cubic-bezier(0.61, 1, 0.88, 1) | sine.out |
| Luxurious(高級感) | 素早く始まり、長くゆっくりと滑るように停止 | 1.2 s | cubic-bezier(0.22, 1, 0.36, 1) | power4.out |
| Floaty(浮遊感) | 羽根:ゆっくりと一定、明確な開始や停止がない | 2 s | cubic-bezier(0.37, 0, 0.63, 1) | sine.inOut |
| Dramatic(劇的) | 劇場の幕:盛り上がり、一気に進み、落ち着く | 1.2 s | cubic-bezier(0.87, 0, 0.13, 1) | expo.inOut |
| Wind-up(巻き上げ) | パチンコ:まず後ろに引き、最後にオーバーシュートする | 800 ms | cubic-bezier(0.68, -0.6, 0.32, 1.6) | back.inOut(1.7) |
| Pop(ポップ) | 終点を飛び越えて一度戻る | 450 ms | cubic-bezier(0.34, 1.56, 0.64, 1) | back.out(1.7) |
| Elastic(伸縮) | ゼリー:数回揺れてから収まる | 1 s | linear() (elastic.outからサンプリング) | elastic.out(1, 0.3) |
| Bounce(バウンド) | ボールが着地する | 900 ms | linear() (bounce.outからサンプリング) | bounce.out |
| Mechanical(機械的) | ベルトコンベア:全行程同じ速度 | 1 s | linear | none |
| Stepped(ステップ) | パラパラ漫画:コマ送りでジャンプする | 900 ms | steps(6) | steps(6) |
フィールはどの速度でもそのカーブを維持します:「400 msのSpringy」はSpringyの形状を維持したまま、より速くなります。プレーンなCSSでのスプリング、エラスティック、バウンスは、カーブからサンプリングしたlinear()のリストです。すぐに貼り付け可能な値はreferences/feels.md(「すぐに貼り付け可能なコード」)にあります。スプリングの「bounce」は、SwiftUIやMotionで使用される0~1の値です(減衰比 = 1 − bounce)。
作業の進め方
- まず要素を確認します: どのくらいの頻度で見られるか、インターフェース部分かショーケースモーションか(後述の「フィールを選ぶ前に」)。これにより、動きを減らしたり、まったくなくしたりする場合があります。
- 相手の言葉をフィール+ダイヤル+エフェクトに変換します。後述の「日常の言葉」の表を使用します。2つか3つのフィールが当てはまる場合は、平易な質問を1つするか(またはA/Bトグルを表示します)。
- ビルドする前に、計画を平易な1行で伝えます。例:「見出しがスクロールに合わせて、ゆっくりと優雅に浮かび上がりながら現れます(フィール:Luxurious)。」相手は何かが構築される前に方向転換できます。
- CSS変数または1つの設定オブジェクト(
--motion-dur、--motion-ease、--motion-stagger)を使用して、duration、delay、easingを設定してビルドします。これにより、すべての調整が1つの数値の変更で済みます。「ビルドルール」に従ってください。 - 結果を平易な言葉で報告し、開発者向けの値も添えます。変更があった場合は、before → after を表示します:「少し遅くしました:1.2 s → 1.8 s」。以前の値を保持しておき、「戻す」で正確に復元できるようにします。
- 一貫性を保ちます: サイトのフィールが明確になったら、それをプロジェクトのデザイントークンとしてモーションパレット(後述)に保存することを提案し、すべてのセクションが同じように動くようにします。
サイト全体のモーションパレット
優れたサイトは14ではなく2~3のフィールを使用します:1つはインターフェース部分用、1つはショーケースモーメント用、そして場合によっては1つのアクセント用です。誰かが動きをまったく説明できない場合は、ブランドを3つの単語で尋ね、パレットを1行で提案してください。
| ブランドの雰囲気 | ショーケース | インターフェース | アクセント |
|---|---|---|---|
| 落ち着いている、信頼できる、思いやりがある(ヘルスケア、金融、法律) | Gentle | Crisp | — |
| プレミアム、エディトリアル(ファッション、建築、ホテル) | Luxurious | Crisp | 初回ロード時のみDramatic |
| 大胆、速い、テクニカル(スタートアップ、SaaS、スポーツ) | Snappy | Crisp | Pop |
| フレンドリー、遊び心がある(子供、食品、コンシューマーアプリ) | Springy | Snappy | Pop または Bounce |
| クリエイティブ、表現力豊か(スタジオ、ポートフォリオ、エージェンシー) | Luxurious または Dramatic | Snappy | Wind-up |
| 夢のような、自然(ウェルネス、美容、瞑想) | Floaty(ループ用)、Gentle(コンテンツ用) | Crisp | — |
| レトロ、生々しい(ゲーム、音楽、ブルータリズム) | Stepped | Crisp | Mechanical(マーキー) |
フィールを選ぶ前に
どのくらいの頻度で見られるか?
一度は喜ばれる動きも、10回目には邪魔になります。動きの量を、訪問者がその要素に出会う頻度に合わせてください。
| 頻度 | 例 | モーション |
|---|---|---|
| すべてのページ、すべての訪問で | ナビリンク、ヘッダー、ボタン、フッターリンク、フォームフィールド | 小さく速く:Crisp、または色の変更のみ。キーボードフォーカスは即座にフォーカスリングを表示し、動きはありません。これらのエントランス(ロード時にスライドインするナビゲーション)は、最初のページビューでのみ再生されます。 |
| クリックごとに | ページ遷移 | 短く:600 ms以下。ブランドが遅くてプレミアムな場合でも同様。 |
| ページごとに1回 | ヒーロー、セクションのリビール、ケーススタディカード、統計カウントアップ | フルフィール。スクロールリビールは一度再生され、スクロールバックしても再度再生されません。 |
| 訪問ごとに1回 | イントロローダー、初回ロードのヒーローモーメント | Dramaticで楽しさを演出する余地があります。ローダーは最初のページビューでのみ実行します。 |
パレットのアクセントは、コントロールではなく結果に適用します:カートに追加するボタンの押下は素早く(Crisp)保ち、カートのカウントがポップするようにします。
誰かがすべてのページ要素に遅いフィールを要求した場合、速いバージョンをビルドし、切り替え方法を1行で伝えます:「ナビリンクはすべてのページにあるため、素早く保ちました;遅いバージョンは1つの数値を変更するだけです。」答えを待つ必要はありません。それは相手の判断です。
インターフェース部分か、ショーケースか?
- インターフェース部分: 訪問者は何かをしようとしています。ナビゲーションドロップダウン、モバイルメニュー、タブ、アコーディオン、モーダル、ツールチップ、フォームフィードバック、フィルター。これらは300 ms以下に保ちます。フィールは問いません。モバイルメニューとモーダルは400 msまで許容されます。終了時は入口の約75%の速度で動作させます:短いdurationをクローズ状態に設定します。
- ショーケースモーション: 雰囲気を演出します。ヒーロー、セクションリビール、画像リビール、マーキー、バックグラウンドループ、初回ロードモーメント。フィール自体の速度が適用され、長くても問題ありません。
要素ごとのデフォルト(感触が指定されていない場合)
ここでの速度は、フィール自体の速度を上書きします。「安っぽい」「バウンドしすぎ」などのフィードバックがあれば、これらのデフォルトを上書きします。
| 要素 | フィール | 速度 |
|---|---|---|
| ボタン、リンク、トグル、ホバー、ツールチップ | Crisp | 150 ms |
| ナビゲーションドロップダウン、タブ、カードホバー | Snappy | 250 ms |
| アコーディオン、FAQ | Smooth | 300 ms |
| モバイルメニュー、モーダル、ドロワー、シート | Springy | 400 ms |
| ドラッグ&リリース | Springy | 600 ms |
| スライド、カルーセル、画面を横切る動き | Smooth | 500 ms |
| テキストと画像のリビール(24 pxフェードアップ、60–80 msスターガー) | パレットのショーケースフィール。手がかりがなければSnappy | フィール自身の速度 |
| ページ遷移 | Smooth | 600 ms |
| ヒーローモーメント、初回ロード | Dramatic | 1.2 s |
| バックグラウンドループ、アンビエントシェイプ | Floaty | 2 s |
| 成功状態、バッジ | Pop | 450 ms |
| ローダー、マーキー、スクロール連動モーション | Mechanical | 必要に応じて |
日常の言葉
これらを使用して変換します。左の列は人々が実際に言う言葉であり、どれもモーションの知識を必要としません。長い会話では、各変換を一度示したら、その後は黙って適用します。
言葉 → フィール
| 相手の言葉 | 読み替え | 尋ねるタイミング |
|---|---|---|
| プレミアム、高級、エレガント、クラス感、ハイエンド、ラグジュアリー、「雑誌のよう」、「ゆっくりで自信に満ちている」 | Luxurious | — |
| スムーズ、流動的、バターのよう、シームレス、シルキー、「滑るように」 | Smooth(横に動く)または Gentle(現れる) | 要素だけでは明らかでない場合:「端から端まで均等に滑るように動かしますか、それとも柔らかく現れてフェードアウトしながら止まりますか?」 |
| 柔らかい、落ち着いた、リラックスした、静かな、居心地が良い、温かい、「派手じゃない」 | Gentle | — |
| 微妙、ほとんど気づかない、「目立たせたくない」 | Crisp(インターフェース)または Gentle(コンテンツ) | — |
| 夢のよう、風通しが良い、浮いている、無重力、「羽のように」、「水中のように」 | Floaty | — |
| 速い、素早い、レスポンシブ、瞬間的、カチカチ、タイト、「電灯のスイッチのように」 | Crisp(小さいもの)または Snappy(大きいもの) | サイズが不明瞭な場合 |
| パンチが効いている、エネルギッシュ、大胆、自信に満ちている、強い、「しっかり着地する」、「態度がある」 | Snappy | — |
| 自然、物理的、生きている、「スマホアプリのよう」、「本物の物体のよう」 | Springy | — |
| 楽しい、遊び心がある、かわいい、フレンドリー、生意気、幸せ | Pop、Springy または Elastic | ほとんど常に:「終点を少し飛び越える感じ、柔らかくバネのように収まる感じ、それともゼリーのように揺れる感じ?」 |
| バウンドする | Bounce(着地してバウンド)または Pop / Springy(オーバーシュートして収まる) | 常に:「ボールが着地するようにバウンドしますか、それとも少しオーバーシュートして収まりますか?」 |
| ゼリー状、ぐらぐら、ゴムのよう、ふにゃふにゃ、ぷるぷる | Elastic | — |
| 映画的、壮大な、「映画のよう」、「ワウ!」な瞬間、力強い、重厚、ビッグリビール | Dramatic | — |
| アニメっぽい、「最初に巻き上げる」、「パチンコのよう」 | Wind-up | — |
| ロボット的、一定、安定した、「ベルトコンベアのよう」、ティッカー | Mechanical | — |
| レトロ、カクカク、ストップモーション、ピクセル、グリッチー、「古いビデオゲームのよう」、パラパラ漫画 | Stepped | — |
| モダン、かっこいい、良い、きれい、「目立たせて」、「見栄えを良くして」、「アニメーションを追加して」、「生き生きとさせて」 | それだけでは不十分 | 常に:そのコンテキストに合う3つのフィールを平易な言葉で提案するか、ブランドを3つの単語で尋ねます(「目立たせて」はPopフィールを意味する場合もあれば、単に「もっと目立つように」という意味の場合もあります) |
フィードバック → ダイヤル
| 相手の言葉 | 変更内容 |
|---|---|
| 速すぎる、慌ただしい、「瞬きすると見逃す」、「見えない」 | 速度 × 1.5 |
| 遅すぎる、鈍い、ラグがある、「永遠に続く」、「待たされる」 | 速度 ÷ 1.5。インターフェース部分の場合は、300 msの制限も確認してください。 |
| 唐突、荒い、ぎくしゃく、「ガタンと所定の位置に落ちる」、「急に止まりすぎる」 | 停止:よりソフトに。power2.out → power3.out → power4.out → expo.out の順に1段階進めます(CSSの値は references/feels.md にあります) |
| どろどろ、最後が「だらだら」、「のろのろ」、「落ち着くのに時間がかかる」 | 停止:よりしっかりと(テールを短く)、または速度アップ |
| 弱々しい、活気がない、「もっとパンチが必要」、「決まらない」 | 停止をしっかり+速度 ÷ 1.5、またはSnappyに変更 |
| バウンドしすぎ、「やりすぎ」、安っぽい、子供っぽい、「オーバーな」 | オーバーシュートを1段階下げる:Pop cubic-bezier(0.34, 1.56, 0.64, 1) → 少し cubic-bezier(0.34, 1.4, 0.64, 1) → なし(Snappy) |
| 安っぽい | 通常は動きすぎ:距離を下げ、オーバーシュートを下げる。遅い場合は速度 ÷ 1.5 |
| 飛び跳ねる、ガタつく、「突然どこからともなく現れる」 | 何もないところから成長するか、オーバーシュートしている:scale(0.95)から開始(ビルドルール)、オーバーシュートを1段階下げ、距離を下げる |
| 硬い、ロボット的、死んでいる、「もっと生き生きとさせて」 | オーバーシュートを1段階上げる、またはSpringyに変更 |
| 平坦、退屈、「何も起こらない」、「気づかない」 | スターガーを上げる、または距離を上げる |
| うるさい、気が散る、「やりすぎ」、うざい | 強度を下げ、スターガーを下げる。うざいということは、多くの場合、見られる頻度が高すぎることを意味します:「どのくらいの頻度で見られるか?」を確認してください。 |
| 「めまいがする」、「気分が悪くなる」 | パララックス、大きなスケーリング、長距離の動きを削除。動きを抑制した場合のフォールバックを確認。 |
| 遅すぎる/早すぎる | 遅延を100 ms単位で減らす/増やす |
| ピンとこない、「なんか違う」、「何が悪いかわからない」 | 推測しない:「速度ですか、始まり方ですか、止まり方ですか、最後の小さなバウンドですか?」と尋ねるか、2つのバージョンを並べて表示します |
ビルドルール
- 動きは
transform、フェードはopacityで。width、height、top、left、marginをアニメーションさせないでください。スクロール中に途切れます。アコーディオンの場合、grid-template-rows: 0fr → 1frは認められた例外です(コンテンツはmin-height: 0; overflow: hiddenの内部ラッパーに配置します)。transition: allは絶対に使用せず、プロパティを指定してください。 - 何もないところから成長させないでください。 スケールインは
scale(0.95)とopacity: 0から開始します(大きなポップの場合は 0.9)。scale(0)から開始しないでください。 - 成長元を指定します。 「上から下に開く、左から右に開く、中央から開く」というように、開始のアンカーを常に設定します。CSS の場合は
transform-origin: top、GSAP の場合はtransformOrigin: 'top'です。 - エントランスとエグジットをペアにします。 何かが入ってくる場合は、出ていく方法も定義します。通常、出口は入口の逆です:
transformの変更を元に戻し、opacity: 0にフェードアウトし、duration を入口の約 75% にします。反復(ループ、マーキー、アンビエント)は閉じた形状であり、個別の入口と出口は必要ありません。 - ステートは次のステートを考慮します。 ドロップダウンが開いている場合(開いている)、ポップオーバーはその上に開く(開いている)か、下に開く(閉じている)か。これが entry animation 全体に影響を与える可能性があるため、単一の要素ではなくコンポジションを考慮してください。
- 入口は最初のページビューのみ。 訪問者が戻ってきたとき(戻るボタン、タブの再アクティブ化)は、入口のアニメーションを再生しないでください。
document.visibilityStateを確認するか、sessionStorageにフラグを使用します。訪問者が 30 分以上経過して戻ってきた場合(ハードリロードまたはクリアされたキャッシュ)、入口は再度再生される可能性がありますが、通常は避ける必要はありません。 - スターガーは、設定されている場合は
--motion-staggerを使用します。 スターガーの値(間隔)は 60 ms から開始し、次のグループの遅延を追加しない場合があります(各アイテムは前のアイテムの開始後 60 ms で開始します)。子アイテムに--motion-stagger-index(0 から始まる)を設定し、ルールtransition-delay: calc(var(--motion-stagger) * var(--motion-stagger-index))を作成すると便利です。 - 1 つのアニメーションは 1 つの動き、1 つの目的。 要素が 2 つの異なることを行う場合(フェードインしてスライドする)、それらは同じタイミングになります。それができたら、別々の効果にできるかどうかを検討します。フェード + スライド + スケールは、過剰であることがよくあります。
アクセシビリティ
prefers-reduced-motionはセーフティネットです。 動きがコンテンツにとって不可欠でない限り(ローダーやスクロール連動のストーリーテリングのように)、@media (prefers-reduced-motion: no-preference)でラップするか、will-changeを削除し、transition-duration: 0.01msを設定し、パララックスと背景ループを削除し、入口のアニメーション(最初のページビュー)をスキップしてすぐに表示します。- 動きはすべてを変えてはいけません。 遷移するときは、常に開始状態を維持します(たとえば、
opacity: 1が保証されるまで、pointer-events: noneをアニメーションに使用しないでください)。 - キーボードフォーカスは即座に表示します。 フォーカスリングに遅延はありません。オーバーシュートやバウンドもありません。
transition: outline-offset 100msで問題ありません。 - タッチデバイスは速度の 75% で実行します。 人間の指はマウスより遅いため、75% は物理的な操作のように感じられます。
コードへの配置(プロジェクト構造)
設定はプロジェクト内のデザイントークンまたは単一の CSS ファイルに配置されます。構造の例:
:root {
--motion-dur: 300ms;
--motion-ease: cubic-bezier(0.33, 1, 0.68, 1);
--motion-stagger: 60ms;
}
JavaScript(GSAP や Framer Motion など)の場合:
const motionConfig = {
duration: 0.3,
ease: 'power2.out',
stagger: 0.06,
}
レビューチェックリスト
各アニメーションを公開前にチェックします。
- 速度は適切ですか? あまりにも速くて見えない、または遅すぎて待たされる感じはありませんか?
- イージングは意図したフィールと一致していますか? Crisp はしっかりと止まる Snappy とは異なります。
- 動きは
transformとopacityを使用していますか? レイアウトプロパティは使用していませんか? -
scale(0)から始まるものはありませんか? すべてのスケールインは 0.95 から始まりますか? - 目立ちすぎたり、注意をそらしたりしていませんか? 特に繰り返し表示される要素の場合。
- 動きの抑制設定は適用されていますか? 動きを抑制する訪問者にとって、アニメーションは不快なものではありませんか?
- キーボードフォーカスは即座に表示されますか? フォーカスリングにアニメーション遅延はありませんか?
- タッチデバイスでは動きが速すぎませんか? 速度は 75% にされていますか?
- エントランスとエグジットはペアになっていますか? 入ってくる要素は、適切に出ていく方法を持っていますか?
- この要素がインターフェース要素の場合、300 ms の制限を超えていませんか?
- 入口のアニメーションは最初のページビューのみですか?