make-interfaces-feel-better について
UI の構築やレビューに向けて、タイポグラフィ、サーフェス、モーション、アイコン、パフォーマンスの指針をまとめたデザインスキルです。深刻度や検証要件を含むレビュー形式も定めています。
主な機能
- 01文字、サーフェス、モーションの指針
- 02アイコンのスタイルと状態の指針
- 03パフォーマンスとタップ領域の確認
- 04クイック/フルのレビュー形式
- 05指摘と検証の構造化フォーマット
活用シーン
- 01既存のスタイルシステムを保って UI コードを調整
- 02インタラクション状態やアニメーションの確認
- 03深刻度と根拠を添えて UI の問題を報告
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jakubkrehel/ make-interfaces-feel-better --skill make-interfaces-feel-betterインストール後、Claude Code で/make-interfaces-feel-betterを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
animations.mdicons.mdperformance.mdsurfaces.mdtypography.mdagents/openai.yaml詳細
インターフェースをより心地よくする細部
優れたインターフェースは、ひとつの要素だけで実現するものではありません。通常、小さな細部が積み重なって、優れた体験になります。UI コードを作成したりレビューしたりする際は、これらの原則を適用してください。修正を提案または記述する前に、プロジェクトで既に使われているスタイリングシステムを特定し、そのシステムに沿って変更を表現してください。Tailwind のプロジェクトでは Tailwind、CSS のプロジェクトではプレーンな CSS、CSS-in-JS が確立されているプロジェクトではその手法を使います。見た目を少し整える修正のためだけに、別のスタイリングシステムを導入しないでください。
レビュー時はインターフェースの動きをゆっくり確認してください。ブラウザーのアニメーションパネルで動きを 10% の速度で再生し、ホバー、フォーカス、アクティブ、読み込み中、空の各状態を確認します。10% の速度で違和感がある部分は、通常の速度でも微妙に問題があります。
クイックリファレンス
| カテゴリー | 使用する場面 |
|---|---|
| タイポグラフィ | テキストの折り返し、フォントのスムージング、等幅数字 |
| サーフェス | 角丸、視覚的な位置合わせ、影、画像のアウトライン、クリック領域 |
| アニメーション | 中断可能なアニメーション、入場/退場のトランジション、アイコンのアニメーション、押下時のスケール、動きの抑制 |
| アイコン | アイコンの線の太さ、currentColor による状態、アウトラインと塗りつぶしの使い分け、サイズ、RTL 時の反転 |
| パフォーマンス | トランジションの詳細度、will-change の使い方 |
基本原則
1. 同心円状の角丸
外側の角丸 = 内側の角丸 + パディングです。入れ子になった要素の角丸が合っていないことは、インターフェースに違和感を与える最も一般的な原因です。
2. 幾何学的な位置合わせより視覚的な位置合わせ
幾何学的に中央揃えして違和感がある場合は、視覚的に位置を合わせます。アイコン付きボタン、再生三角形、非対称なアイコンには、いずれも手動での調整が必要です。
3. 高さの表現には影、構造の表現には境界線
ボタン、カード、コンテナーなど、奥行きを出すためだけに境界線を使っている要素には、透明度を調整した複数の box-shadow 値を使うのがおすすめです。仕切り線、レイアウトの区切り線、選択状態やフォーカス状態など、構造や状態を伝える境界線は残します。
4. 中断可能なアニメーション
インタラクティブな状態の変更には CSS トランジションを使います。アニメーションの途中でも中断できるためです。一度だけ実行する段階的なシーケンスには、キーフレームを使います。
5. 入場アニメーションの分割と段階的表示
シーケンスによって階層を伝えられる、頻度の低い段階的な入場演出では、コンテンツを意味のあるまとまりに分割し、ひとつのコンテナーをアニメーションさせるのではなく、約 100ms ずつずらして表示します。日常的に繰り返される高頻度のインタラクションでは、表示をずらさないでください。
6. 控えめな退場アニメーション
高さ全体を使う代わりに、小さく固定した translateY を使います。退場アニメーションは入場アニメーションより控えめにします。入場と退場のどちらのトランジションにも ease-out を使います。
7. 状況に応じたアイコンアニメーション
表示/非表示を切り替えるのではなく、アイコンを opacity、scale、blur でアニメーションさせます。値は必ず次のとおりにしてください。スケールは 0.25 から 1、不透明度は 0 から 1、ぼかしは 4px から 0px です。プロジェクトの package.json に motion または framer-motion が含まれている場合は、そのパッケージのインポートパス(または両方が使われている場合は、近くで確立されているインポート方法)に合わせ、transition: { type: "spring", duration: 0.3, bounce: 0 } を使います。bounce は必ず 0 にしてください。モーションライブラリがインストールされていない場合は、両方のアイコンを DOM に残し(片方は絶対配置)、cubic-bezier(0.2, 0, 0, 1) を使った CSS トランジションでクロスフェードします。依存関係を追加せずに、入場と退場の両方をアニメーションできます。
8. フォントのスムージング
macOS では、テキストをより鮮明に表示するため、ルートレイアウトに -webkit-font-smoothing: antialiased を適用します。
9. 等幅数字
動的に更新される数字には font-variant-numeric: tabular-nums を使い、レイアウトのずれを防ぎます。
10. テキストの折り返し
見出しには text-wrap: balance を使います。孤立する行を避けるため、本文には text-wrap: pretty を使います。
11. 画像の輪郭
画像に控えめな 1px の輪郭を低い不透明度で追加し、奥行きを一貫させます。ライトモードでは純粋な黒(oklch(0 0 0 / 0.1))、ダークモードでは純粋な白(oklch(1 0 0 / 0.1))にしてください。スレート、ジンクなどのほぼ黒の色や、色味のあるニュートラルカラーは使わないでください。色味のある輪郭は下地の表面色を拾い、画像の縁に汚れが付いているように見えます。
12. 押下時のスケール
クリック時に控えめな scale(0.96) を適用すると、ボタンに触覚的なフィードバックを与えられます。常に 0.96 を使用してください。0.95 未満の値は使わないでください。それより小さい値は過剰に感じられます。動きが注意をそらす場合は無効にできるよう、static プロパティを追加してください。
13. ページ読み込み時のアニメーションをスキップ
初回レンダリング時の入場アニメーションを防ぐため、AnimatePresence に initial={false} を指定します。意図した入場アニメーションが損なわれないことを確認してください。
14. transition: all は使用しない
プロパティを正確に指定してください。例:transition-property: scale, opacity。Tailwind の transition-transform は transform, translate, scale, rotate を対象とします。
15. will-change は控えめに使用
GPU で合成できる transform、opacity、filter にのみ使用してください。will-change: all は使用しないでください。最初のフレームでカクつきが見られた場合にのみ追加してください。
16. 最小ヒット領域
タッチやモバイル環境では、インタラクティブな要素のヒット領域は 44×44px を優先します。情報量の多いデスクトップインターフェースでは、少なくとも 40×40px にしてください。表示される要素が小さい場合は、疑似要素で領域を拡張します。2 つの要素のヒット領域を重ねないでください。
17. アイコンの線幅をテキストの太さに合わせる
テキストの隣にあるアイコンは、テキストと視覚的な太さを揃えます。通常(400)のテキストの隣では線幅 1.5px、セミボールド(600)の隣では 2px にします。アイコンセットごとに線幅を統一し、同じ画面内でライブラリを混在させないでください。
18. SVG は 1 つだけにし、状態ごとに色を変更
アイコンには currentColor を使用し、ホバー、選択、無効などの状態は、別々のアセットではなく CSS の色と不透明度で表現します。デフォルトはアウトライン版とし、アクティブ状態には塗りつぶし版を使用します。
19. 動きは控えめに
頻繁に発生する操作にカスタムアニメーションを使わないでください。操作のたびに注意を奪うためです。動きだけでフィードバックを伝えてはいけません。アニメーションを伴う状態変化には、色、アイコン、ラベルなどの静的な手掛かりも必要です。
よくある間違い
| 間違い | 修正方法 |
|---|---|
| 親要素と子要素に同じ角丸を設定する | outerRadius = innerRadius + padding を計算する |
| アイコンが中央からずれて見える | パディングで視覚的に調整するか、SVG を直接修正する |
| 高さを偽装するためだけに境界線を使う | 透明度を設定したレイヤー状の box-shadow を使い、構造や状態を示す境界線は残す |
| 不自然な段階的入場や、文脈を損なう退場 | 頻度の低い入場は段階的に表示し、文脈を保つ退場は控えめにする |
| 数字によってレイアウトがずれる | tabular-nums を適用する |
| macOS でテキストが太く見える | ルートに antialiased を適用する |
| ページ読み込み時にアニメーションが再生される | AnimatePresence に initial={false} を追加する |
要素に transition: all を指定する | プロパティを正確に指定する |
| 最初のフレームでアニメーションがカクつく | will-change: transform を控えめに追加する |
| 小さなコントロールのヒット領域が狭い | タッチ/モバイルでは疑似要素で 44×44px に、情報量の多いデスクトップ UI では少なくとも 40×40px に拡張する |
| 太字テキストの隣にあるアイコンの線が細すぎる | 線幅をテキストの太さに合わせる |
| 状態ごとに別々のアイコンアセットを使う | currentColor を使った SVG を 1 つ用意し、状態は CSS で表現する |
| どこでも塗りつぶしアイコンを使う | デフォルトはアウトラインとし、塗りつぶしはアクティブ状態にのみ使う |
| ホバーやキー入力のたびに入場アニメーションを再生する | 即時に反応させるか、不透明度/色の遷移を ≤150ms にする |
レビュー出力形式
レビューのモードが指定されていない場合は、full を使用します。
| モード | 対象範囲 | 指摘の上限 |
|---|---|---|
quick | 主要なユーザーパスと、利用頻度の高い状態。HIGH と MEDIUM の問題のみ報告 | 5 |
full | タイポグラフィ、表面、アニメーション、アイコン、パフォーマンスを含む、依頼された範囲全体 | 15 |
スコープとカバレッジ
モード、正確なスコープ、フレームワーク、スタイリング規約、およびレビュー境界があれば明記します。実際に検査した内容を示します。
| カテゴリ | 検査したエビデンス | 結果 |
|---|---|---|
| タイポグラフィ | ファイル、コンポーネント、状態、またはチェック | 指摘件数、Clear、または理由を添えた Not reviewed |
Quick Reference の 5 カテゴリをすべて含めてください。検査していない領域をレビュー済みであるかのように示唆してはいけません。
指摘事項
指摘事項は原則ごとにグループ化します。Severity、Location、Before、After、Why 列を持つ Markdown テーブルを使用します。実施または提案したすべての変更を含め、一部だけにしないでください。個別の「Before:」/「After:」行は決して使用しないでください。
- Severity:
HIGHはインタラクションをアクセス不能、誤解を招く、読めない、または繰り返し妨害するものにします。MEDIUMは目立つユーザビリティまたは一貫性の問題を生み出します。LOWは孤立した磨き込みであり、fullモードにのみ現れます。 - Location:
path/to/file:lineを引用します。成果物にソースファイルがない場合は、代わりに正確な画面とコンポーネントを引用します。 - Before / After: 現在の実装と、実行可能な代替案を示します。
- Why: 違反した原則を明示し、そのユーザーへの影響を説明します。
繰り返し発生するシステム的な問題は 1 行に統合し、影響を受けるすべての箇所を列挙します。指摘のない原則は省略し、上限に達するためにレポートを水増ししてはいけません。
例
同心のボーダー半径
| Severity | Location | Before | After | Why |
|---|---|---|---|---|
| LOW | src/Card.tsx:28 | カードに rounded-xl + 内側のボタン(p-2)に rounded-xl | カードに rounded-2xl(8 + 8 = 16)、内側のボタンに rounded-lg | ネストされた角は同心であるべき |
| LOW | src/card.css:11 | ネストされた両方のサーフェスに border-radius: 16px | 外側を 24px、内側を 16px にして 8px のパディング | 等しいネスト半径は内側のサーフェスを窮屈に見せる |
等幅数字
| Severity | Location | Before | After | Why |
|---|---|---|---|---|
| MEDIUM | src/Counter.tsx:17 | <span>{count}</span> | <span className="tabular-nums">{count}</span> | プロポーショナル数字は変化する値がずれる原因になる |
| LOW | src/timer.css:8 | タイマーにデフォルトの数字 | タイマーに font-variant-numeric: tabular-nums を追加 | 等幅数字はタイマーを安定させる |
押下時のスケール
| Severity | Location | Before | After | Why |
|---|---|---|---|---|
| LOW | src/Button.tsx:19 | <button className="..."> | active:scale-[0.96] transition-transform を追加 | 押下フィードバックによりコントロールが反応的に感じられる |
| MEDIUM | src/button.css:24 | 押下時に scale(0.9) | scale(0.96) に引き上げる | 0.95 未満は誇張されて感じられる |
検討したが見送ったもの
quick モードでは 1~3 件、full モードでは 2~5 件の実際の候補を含めます。
| Location | Candidate | Rejected because |
|---|---|---|
src/Card.tsx:28 | シャドウを強くする | 既存の奥行きは共有サーフェストークンと一致しており、1 つのカードを変更すると一貫性が損なわれる |
埋め草をでっち上げないでください。スコープに境界線上の候補がそれより少ない場合は、存在するものを含め、その旨を述べてください。
検証と判定
指摘事項の後に:
- Verification: 実行した正確なコマンドまたはインタラクションと、観察された結果を列挙します。関連するすべての状態を歩き、アニメーションが関与する場合は 10% 速度でモーションを検査します。チェックを実行しなかった場合は、Not verified とラベル付けし、何が残っているかを述べます。
- Verdict:
HIGHの指摘が残っている場合はBlock、MEDIUMまたはLOWの指摘のみが残っている場合はNeeds changes、実行可能な指摘が残っていない場合にのみApproveとします。未検証のチェックをすべて判定の横に列挙します。
指摘がない場合は、指摘テーブルを省略し、「No actionable interface-polish findings」と述べ、検証と見送った候補を報告し、Approve で終了します。