mcpField
B
better-ui

better-ui

github.com/jakubkrehelデザイン・UI9.0k40.6k 回インストール3 日前に更新
リポジトリ

better-ui について

better-uiは、操作が正しく機能した後に、画面の表面、アイコン、モーションを点検・調整するデザインスキルです。具体的なスタイル規則と、重要度別にUIの仕上げに関する問題を報告する形式を定めています。

主な機能

  1. 01表面の角丸とシャドウの規則
  2. 02アイコンの配置と色状態の指針
  3. 03トランジションとモーションの仕様
  4. 04モーション低減とホバー動作
  5. 05UI課題の重要度と報告形式

活用シーン

  1. 01コンポーネントのモーションと状態の監査
  2. 02アイコンと表面の一貫性の確認
  3. 03重要度別のUI仕上げ課題の報告

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/jakubkrehel/skills --skill better-ui

インストール後、Claude Code で/better-uiを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

animations.md
enter-exit.md
icon-transitions.md
icons.md
performance.md
surfaces.md
agents/
openai.yaml

詳細

UI の仕上げ

このスキルには、サーフェス、アイコン、モーションの視覚的な仕上げと、それぞれの詳細に使用する正確な値が含まれています。基盤となるインタラクションが適切に機能してから適用してください。仕上げに関する指摘が、壊れたインタラクションより優先されることはありません。

正確な値と任意の仕上げ

以下の値は正確な値であり、おおよその範囲ではありません。cubic-bezier(0.2, 0, 0, 1) は cubic-bezier(0.4, 0, 0.2, 1) ではなく、0.96 は 0.95 ではありません。光学的な微調整と同心パディングのしきい値は例外です。これらは出発点として、目視で判断してください。

特に規則で値が指定されていない場合は、プロジェクトのコンポーネントライブラリ、トークン、密度を維持し、そのモーションの表現に合わせてください。影を使わないスタイルなど、意図的で一貫したプロジェクトの規約は好みであり、指摘事項ではありません。同じ詳細がプロジェクト内で異なる方法で実装されている場合は、指摘事項です。

テキストの折り返し、フォントのレンダリング、等幅数字、テキストの間隔は better-typography の対象です。ヒット領域、キーボードサポート、ARIA、動きを減らす要件は better-accessibility の対象です。グループ化、セクション間隔、ブレークポイント、空間的な RTL は、方向アイコンの反転を除き、better-layout の対象です。カラートークンとコントラストの測定は better-colors の対象です。

外側の角丸は内側の角丸にパディングを加えた値

入れ子になったサーフェスに、均等で目に見えるインセットがある場合、外側の角丸は内側の角丸にパディングとボーダー幅を加えた値にします。パディングが 24px を超える場合、または意図的に非対称な場合は、各レイヤーを別々のサーフェスとして扱い、それぞれの角丸トークンを維持してください。実装例は surfaces.md にあります。

形状のずれが目につく場合は光学的に揃える

幾何学的な中央揃えに違和感がある場合は、目視で微調整してください。ボタンのアイコン側のパディングを 2px 小さくし、再生用の三角形を先端側にずらし、非対称なグリフは SVG 自体を修正してください。実装例は surfaces.md にあります。

高さにはシャドウ、構造にはボーダー

奥行きを出すためだけに使われているボーダーは、透明度を重ねた box-shadow の値に置き換えてください。区切り線、セパレーター、テーブルセル、選択状態にはボーダーを維持してください。フォーム入力にもボーダーを維持してください。better-accessibility では、その境界に非テキストコントラスト 3:1 が必要です。フォーカスリングも better-accessibility の対象です。

強制カラー表示モードでは、すべての box-shadow が削除されます。そのモードでも境界線が表示されるよう、シャドウリングの下に border: 1px solid transparent を維持してください。実装例は surfaces.md にあります。

画像の輪郭線には純粋な黒または白を使う

コンテンツ画像には、内側に 1px インセットした 1px のアウトラインを付けてください。ライトモードでは oklch(0 0 0 / 0.1)、ダークモードでは oklch(1 0 0 / 0.1) を使います。パレットのほぼ黒、色味のあるニュートラルカラー、アクセントカラーは使わないでください。画像の端に色付きの縁として現れるためです。ロゴやイラストなど、透明なアートワークには適用しないでください。実装例は surfaces.md にあります。

インタラクティブな状態にはキーフレームではなくトランジションを使う

インタラクティブな状態の変化には CSS トランジションかモーションライブラリのスプリングを使ってください。これらは、ユーザーがアニメーションの途中で逆の操作をした場合に、目標値を切り替えます。キーフレームは固定されたタイムラインで動作し、逆方向には切り替えられないため、一度だけ実行されるシーケンスに限定してください。animations.md を参照してください。

押下時は 0.96 に縮小

ボタンを押したときは 150ms かけて ease-out で 0.96 に縮小し、無効状態のボタンは縮小させないでください。動きが気になる場合は、既存のコンポーネントバリアント API または static プロパティを使って、ボタンごとに無効化できるようにしてください。CSS、Tailwind、Motion 向けの実装例を参照してください。

高頻度のインタラクションには即座に応答する

キー入力、行へのホバー、タブの切り替えには即座にフィードバックを返すか、opacity または background-color のトランジションを 150ms 以下にしてください。表現豊かなモーションは、ビューの初回読み込み、成功状態、空の状態など、頻度の低い場面に限定してください。

アニメーションによる状態変化には必ず、色、アイコン、ラベルのいずれかによる静的な手がかりも残してください。モーションを唯一のフィードバック手段にしてはいけません。

モーションを reduced-motion の設定に従わせる

要件は better-accessibility が管理しており、ここにあるレシピはすべてこの要件に従います。動き、スケール、ぼかしは prefers-reduced-motion: no-preference の場合にのみ実行します。視差効果を抑える設定が有効な場合は、要素を瞬時に消すのではなく、代わりに不透明度のクロスフェードを使用します。CSS、Tailwind、Motion のレシピは animations.md を参照してください。

頻度の低い登場アニメーションは100msずつずらす

段階的な登場で順序が階層を伝える場合は、コンテンツをタイトル、説明、アクションなどの意味のあるまとまりに分けます。それぞれを 100ms ずつずらし、不透明度、4px のぼかし、12px の translateY を使って、ease-out で 300ms かけて登場させます。日常的なインタラクションでは、登場タイミングをずらさないでください。enter-exit.md を参照してください。

退場は登場より短く、小さくする

不透明度、4px のぼかし、固定値 -12px の translateY を使い、ease-out で 150ms かけて退場させます。コンテナの高さ全体を使ってはいけません。ドロワーを閉じる場合など、移動先に意味があるときに限り、完全にスライドアウトさせます。モーションで情報が増えない場合は、要素を瞬時に削除します。enter-exit.md を参照してください。

初回レンダリングでは状態アニメーションをスキップする

状態の切り替えをラップする AnimatePresence に initial={false} を設定し、マウント時にデフォルト状態がアニメーションで表示されないようにします。段階的に登場するヒーローなど、意図的な登場アニメーションの周囲には設定しないでください。animations.md を参照してください。

コンテキストに応じたアイコンを正確な値でクロスフェードする

再生から一時停止、コピーからコピー済みなど、頻度の低い状態変化でアイコンを切り替える場合は、クロスフェードさせます。スケールは 0.25 から 1、不透明度は 0 から 1、ぼかしは 4px から 0px に変化させます。モーションライブラリを使う場合は { type: "spring", duration: 0.3, bounce: 0 } を使用し、バウンスは常に 0 にします。モーションライブラリを使わない場合は、両方のアイコンを DOM に保持し、cubic-bezier(0.2, 0, 0, 1) で 300ms かけてクロスフェードさせます。

タブのアイコン切り替えと、行にホバーしたときに表示されるアクションは、頻度の高いインタラクションには即座に応答するに該当します。どちらのレシピも icon-transitions.md にあります。

テーマ切り替え時のトランジションを抑制する

テーマの切り替え時はすべてのトランジションを無効にし、スタイルを強制的にフラッシュした後、次のフレームでトランジションを復元します。これを行わないと、すべての色のトランジションが一度に発生し、切り替えがにじんで見えます。レシピ を参照してください。

変化するプロパティだけをトランジションさせる

transition-property: scale, opacity のように、対象のプロパティを明示し、all は使わないでください。performance.md を参照してください。

will-change ではアニメーション対象のプロパティを指定する

初回フレームのカクつきを確認した場合にのみ will-change を追加し、アニメーションするプロパティを指定します。scale には scale、transform には transform を指定してください。対象はトランスフォーム系のプロパティ、opacity、filter に限定し、all は使わないでください。performance.md を参照してください。

ホバー効果はホバー可能なポインターに限定する

ホバー専用のスタイルは @media (hover: hover) の中に記述します。タッチ操作では、タップ後も :hover が残り、選択状態のままのように見えるためです。Tailwind 4 の hover: バリアントはすでにこのクエリの中でコンパイルされますが、Tailwind 3 ではそうなりません。コントロール独自の押下状態を表示する場合は、デフォルトの灰色のフラッシュが重ならないよう、-webkit-tap-highlight-color: transparent を設定します。

オーバーレイ内にスクロールをとどめる

スクロール可能なダイアログ、ドロワー、メニュー、サイドパネルには overscroll-behavior: contain を設定し、端までスクロールしても背後のページがスクロールしないようにします。

アイコンのストロークをテキストの太さに合わせる

アイコンの表示上のストロークは、隣接するテキストの太さに合わせ、400 では 1.5px、700 では 2.5px にします。1つのサーフェスでは、アイコンライブラリを1つだけ使用します。表、サイズ、グリッドのルールは icons.md にあります。

状態ごとに色を変える単一の SVG

アイコンでは currentColor を使用し、個別のアセットではなく、CSS の色と不透明度でホバー、選択済み、無効の各状態を表します。デフォルトのバリアントはアウトラインで、塗りつぶしはアクティブな状態を示します。dir="rtl" の場合は、読み取り方向に意味が従うアイコンのみを反転します。icons.md を参照してください。

完了前の確認事項

検出内容修正方法
パディングのある親要素と子要素に、同じ rounded-* または border-radius が設定されている外側の角丸にパディング分を加える
隣接する border がない box-shadow: 0 0 0 1px のリングborder: 1px solid transparent
img に outline-slate-*、outline-zinc-*、または 16 進数のアウトライン色が設定されているoutline-black/10 と dark:outline-white/10
transition-all または transition: all変化するプロパティを明示する
:hover、.open、またはその他の切り替えクラスに animation: が設定されている同じプロパティにトランジションを設定する
active:scale-95、scale-90、または 0.96 未満の whileTap0.96
:disabled の除外指定がない :active のスケールenabled:active: または :not(:disabled):active
bounce: に 0 以外が設定されているbounce: 0
animation のみで表示されるベースルールに opacity: 0 がある非表示状態を from キーフレームに設定し、animation-fill-mode: both を指定する
prefers-reduced-motion、motion-safe:、または MotionConfig による制御がない translate、scale、filter、motion.* のアニメーション動きを制御し、動きを抑える設定では不透明度のクロスフェードを使用する
色のトランジションとテーマ切り替えを使っているが、disableTransitionOnChange も上書き設定もないテーマ切り替え時の抑制レシピを適用する
will-change: all がある、またはアニメーションしない要素に will-change があるアニメーションするプロパティを明示するか、削除する
アイコン SVG 内に fill="#..." または stroke="#..." があるcurrentColor
@media (hover: hover) の外にプレーン CSS の :hover または Tailwind 3 の hover: があるメディアクエリで囲む
overscroll-behavior が設定されていないダイアログ、ドロワー、メニューに overflow: auto または overflow-y-auto があるoverscroll-behavior: contain

報告

重大度。 キーフレームの切り替えを元に戻せない場合や、タッチ操作でホバー状態が残る場合など、インタラクションを損なうものは HIGH です。better-interface のエスカレーショントリガーのうち 2 つがこれに該当し、見つけた時点で HIGH とします。1 つは prefers-reduced-motion を無視する動き、もう 1 つは動きだけで状態の変化を伝えるものです。サーフェス、アイコン、動きに見られる不整合は MEDIUM です。単独の仕上げ上の問題は LOW です。

検証。 ブラウザーがない場合は、コードからコンポーネントが定義するすべての状態(ホバー、押下、選択済み、読み込み中、空など)と、それぞれの時間およびイージングを確認します。ブラウザーがある場合は、各状態を確認し、ブラウザーのアニメーションパネルで動きを 10% の速度で再生します。実行できなかった確認はすべて Not verified として報告します。

形式。 該当する原則ごとに指摘をまとめ、重大度の高い順に並べます。根本原因ごとに 1 行とし、該当するすべての箇所を記載します。

重大度場所変更前変更後理由

場所 は path/to/file:line 形式です。理由 には、該当する原則とユーザーへの影響を記載します。

HIGH が残っている場合は最後に Block、それ以外の場合は Approve と記載し、残りの作業は表に記載します。確認していない範囲について Approve としてはいけません。報告事項がない場合は「実施可能な UI の仕上げ上の指摘はありません」と記載し、検証状況を報告します。

コメント