better-ui について
better-uiは、操作性が整った後に表面、アイコン、モーションを確認するUIポリッシュ用スキルです。具体的なルールと値を示し、アクセシビリティ、タイポグラフィ、レイアウト、色の確認は関連スキルに委ねます。
主な機能
- 01入れ子状の面の角丸ルール
- 02シャドウ・境界線・画像輪郭の指針
- 03操作時のトランジションと押下スケール
- 04モーション低減とホバー条件
- 05アイコンの色・線幅・方向の規則
- 06重大度別の指摘と検証形式
活用シーン
- 01面の奥行きや角丸の調整
- 02操作状態ごとのモーション確認
- 03アイコンの一貫性とホバー動作のレビュー
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ 23jmo/ jmo-skills --skill better-uiインストール後、Claude Code で/better-uiを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
animations.mdenter-exit.mdicon-transitions.mdicons.mdLICENSEperformance.mdsurfaces.mdagents/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 以下のトランジションを使います。表現豊かなモーションは、画面の初回読み込み、成功状態、空の状態など、頻度の低い場面に限ります。
アニメーションを伴う状態変化にはすべて、色、アイコン、ラベルのいずれかによる静的な合図も用意します。モーションだけを唯一のフィードバック手段にしてはいけません。
動きを軽減する設定に応じてモーションを制御する
要件は 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 を指定します。対象は 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 未満の whileTap | 0.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 の仕上げ上の指摘はありません」と記載し、検証状況を報告します。