UIXHERO

Search(検索)

ユーザーが入力したキーワードでコンテンツを絞り込むUIコンポーネント。インクリメンタルサーチ・サジェスト・空の状態・キーボード操作の設計基準を解説する。

2026年3月1日
更新: 2026年8月28日
23
by Dengen Yosho(DGYS)

ユーザーが入力したキーワードに基づいてコンテンツをリアルタイムに絞り込む(インクリメンタルサーチ)または送信後に結果ページを表示するコンポーネント。入力欄・サジェスト・空の状態・結果一覧の4セットが設計の単位。

この記事を読むと、インクリメンタルサーチとサーバーサイド検索の使い分け・サジェスト(オートコンプリート)のARIA実装・検索結果ゼロ時の空の状態設計・キーボードナビゲーション(矢印キー)の実装パターンが自分でできるようになります。


1. UI例(Preview / Live)

実装で見る(GunjoUI)

この部品を、デザインシステム GUNJO の実装で確かめられます。

2. 定義(Definition)

ユーザーが入力したテキストでコンテンツを絞り込むUIコンポーネント。大きく2種類に分かれる:① インクリメンタルサーチ(入力のたびにリアルタイムでフィルタリング)と② サーバーサイド検索(送信後に結果ページへ遷移)。

FilterとSearchの違い:Searchは「キーワードで探す」。Filterは「条件(カテゴリ・価格・日付)で絞る」。多くのUIは両方を組み合わせて使う。

Command Paletteとの違い:Command Paletteはアプリ全体の機能・コマンドも検索できる高度な検索UI(Ctrl+K)。Searchは特定のコンテンツセット(記事・商品)を探す。


3. 使い分け(When to use / When NOT to use)

3.1 When to use

  • コンテンツ数が多く(20件以上)、スクロールで目的のものを探すのが困難な場合
  • ユーザーが目的のアイテムを特定のキーワードで探せると分かっている場合
  • 記事一覧・商品一覧・ユーザー一覧などのデータ一覧ページ
  • バーのグローバル検索(サイト全体を横断)

3.2 When NOT to use

  • コンテンツが10件以下で全件見渡せる → カテゴリリスト・Filterで十分
  • ユーザーがキーワードで何を検索すべきか分からない → ブラウズ型のナビゲーションを優先する
  • フォーム内での選択 → Select / Combobox を使う

3.3 代替UI(Alternatives)

  • 少量コンテンツの絞り込み → Filter(チェックボックス・ドロップダウン)
  • コマンド検索 → Command Palette
  • フォーム内の選択肢検索 → Select(searchable select)

4. 設計判断の核(Decision Principles)

Searchの核は「入力→サジェスト→結果→空の状態」の4セットを設計すること——入力欄だけ作って「あとは結果が出る」では設計が半分しかない。

判断の優先順位:① インクリメンタルかサーバーサイドか → ② サジェストの有無 → ③ 空の状態 → ④ クリアボタン

  • インクリメンタル vs サーバーサイド:コンテンツが全件クライアントにある(100件以下)ならインクリメンタル。それ以上ならAPIを叩くサーバーサイド検索。デバウンス(300〜500ms)を必ず入れる
  • サジェストはcomboboxパターンで実装role="combobox"role="listbox"aria-expandedaria-selected の4セットが必須。矢印キーナビゲーションもセットで実装する
  • クリアボタンを入力後に表示:入力した値を一発で消せるクリアボタン(×)を value.length > 0 の条件で表示する。ユーザーが入力をやり直すを減らす
  • 空の状態は「何が起きたか+次のアクション」:「0件」だけ表示しない。「〇〇に一致する結果がありません」+「別のキーワードを試す」のセットで設計する

5. 状態設計(States)

5.1 必須状態(Required)

  • Default(空):プレースホルダーのみ表示
  • Focused:フォーカスリング表示、サジェストが開く場合はここから
  • With Value:クリアボタン(×)を表示
  • Loading:サーバーサイド検索で結果待ち中のスピナー
  • Results:検索結果の一覧
  • Empty(0件):結果ゼロの状態メッセージ

5.2 条件付き状態(Conditional)

  • Suggestions(サジェスト表示中):入力中にリストを表示
  • Disabled:検索機能が一時的に使えない場合
  • Error:検索APIのエラー時
状態必須何を伝えるか
Default検索入力を促す
Focused入力中であること
With Value + クリアボタンクリアできること
Loading検索中であること
Results一致した結果
Empty(0件)結果なし+次のアクション
Suggestions候補をサジェスト

6. バリエーション設計(Variants)

検索の「スコープ」と「のタイミング」で選ぶ。

バリアント目的実装
グローバル検索サイト全体を横断検索ナビバーに固定、Command Palette と統合することも
ローカル検索特定ページのコンテンツを絞り込むテーブル・リストの上部に配置
インクリメンタル入力のたびにリアルタイム絞り込みクライアントサイドフィルタリング
サーバーサイド送信で結果ページ遷移<form> + GET リクエスト
Combobox(選択肢検索)フォーム内の選択肢をキーワードで絞るSelect コンポーネントの拡張

禁止パターン:サジェストリストをキーボードで操作できない → 2.1 の combobox パターンに違反する。role="listbox" と矢印キーナビゲーションは必須。


7. パターン集(Good / Bad / How to fix)

7.0 よく崩れる設計パターン(3つ)

  • 空の状態なし:結果が0件の時に何も表示されず、ユーザーが「バグ?」と思う
  • クリアボタンなし:入力した検索語を消すために手動で全選択→Delete が必要
  • comboboxパターン未実装:サジェストが表示されるが、キーボードで選択できない

7.1 Bad(典型3つ)

  • 検索結果が0件の時に空白のコンテンツエリアのみが表示され、ユーザーに何が起きたか伝わらない
  • 長いキーワードを入力した後、クリアボタンがないため全て手動で消す必要がある
  • <div onClick> で作ったサジェストリストに role がなく、スクリーンリーダーと矢印キーが機能しない

7.2 Good(対になる3つ)

  • 0件時に「「〇〇」に一致する結果がありません。別のキーワードで試してください。」と表示する
  • value.length > 0 の時だけ入力欄右端にクリアボタン(×)を表示する
  • role="combobox"aria-expandedrole="listbox"aria-selected の combobox パターンを実装し、↑↓キーで選択・Enter で確定・Escape で閉じるを実装する

7.3 How to fix(手順)

  1. 検索結果コンポーネントに「0件の時のEmptyState」を追加する
  2. 入力欄に value.length > 0 && <ClearButton /> を追加する
  3. サジェストリストを role="listbox" でマークアップし、各アイテムに role="option"aria-selected を付与する
  4. onKeyDownArrowDownArrowUpEnterEscape を処理する

8. ルール(Must / Better)

Must(守らないと壊れる)

Better(品質が跳ねる)


9. アクセシビリティ要件(必須)

Keyboard

  • Tab で検索フィールドにフォーカス
  • Enter で検索実行(サーバーサイド)またはサジェスト選択(インクリメンタル)
  • でサジェストリスト内を移動
  • Escape でサジェストを閉じてフォーカスを入力欄に戻す

Focus

  • フォーカスリングを表示する(focus:ring-2
  • サジェスト表示中は入力欄にフォーカスを保持する(リストにフォーカスを移さない)

Screen Reader

  • <input type="search"> または role="searchbox"
  • サジェスト使用時は combobox パターン:
<input
  type="search"
  role="combobox"
  aria-expanded="true"
  aria-autocomplete="list"
  aria-controls="search-listbox"
  aria-activedescendant="item-2"
/>
<ul id="search-listbox" role="listbox">
  <li id="item-1" role="option" aria-selected="false">Button</li>
  <li id="item-2" role="option" aria-selected="true">Badge</li>
</ul>
  • 結果件数は aria-live="polite" で通知する

Touch / Pointer

  • 検索フィールドの高さは最低44pxを確保する
  • サジェストアイテムのは最低44pxを確保する
  • inputmode="search" でモバイルキーボードをする

Contrast / Readability

  • プレースホルダーのは3:1以上(テキストの4.5:1より緩和されるが最低限必要)
  • 検索アイコンとのコントラストを確保する

10. 実装メモ(Implementation Notes)

  • Next.js でサーバーサイド検索を実装する場合、useRouterpush でURLの ?q= パラメータを更新してページ遷移する。ブラウザの戻るボタンで検索前に戻れるようになる
  • インクリメンタルサーチのデバウンスは useMemo + useCallbacksetTimeout をクリアする実装が最もシンプル
  • combobox の aria-activedescendant は現在フォーカス中のサジェストアイテムの id を入力欄の属性として設定することで、フォーカスを入力欄に置いたまま「選択中」を伝える
  • shadcn/ui の Command コンポーネントは完全な combobox パターンを実装済み。検索 + サジェストが必要な場合は Command を流用するのが最速

11. 関連リンク


12. まとめ

Searchの設計は「入力欄だけ」で終わらせないことが重要です。迷ったら 4. 設計判断の核 に戻り、インクリメンタル vs サーバーサイドの判断・combobox ARパターン・空の状態・クリアボタンの4点を確認してください。「検索結果0件時に何も表示しない」は最も多い実装ミスです——Searchを設計する際は必ず「結果なし」のUIを先に決めることを習慣にしてください。

更新のお知らせ

サイトに載せていない実例や、新しい記事のお知らせはこちらで出しています。

読んだ内容を、自分の画面に当てるとき

UIXHEROは、記事を書くほかに、画面の検品・判定、デザインシステムの構築、実装と改善の伴走を受けています。何を頼めばいいか決まっていない段階の相談も、同じ窓口で受けます。

UIXHEROに頼めることを見る

※ 記事の内容についての質問や、書いてほしいテーマの要望も同じ窓口で受けています

記事をシェア

メールでお知らせを受け取る

最終更新: 2026年8月28日

この記事を書いた人

Dengen Yosho(DGYS)

Dengen Yosho(DGYS)

UI/UXデザイナー兼デザインエンジニア デザイン歴25年以上 情報設計〜UIデザイン〜React/TypeScriptによる実装までを一気通貫で担当 大手企業のDXプロジェクトや決済アプリ領域で、デザインリードとして改善と構築を経験 現在はフリーランスとして、プロダクトのUI/UX改善とデザインシステム構築を支援 長年の実務の中で感じてきたのは、 「良いUI」はセンスではなく、再現可能な判断の積み重ねであるということ UIXHEROは、 心理学や行動科学の知見を、現場で使える設計言語に翻訳するための場所 関心領域は「ユーザーの行動が変わるUI」 人の認知・注意・意思決定の構造を理解し、 “なぜそのUIが機能するのか”を言語化することを目指している

あわせて読みたい

この記事に関連する記事をご紹介します

Bar Chart(棒グラフ)

カテゴリごとの量を棒の長さで比べるチャート。ゼロ基線の扱い、並び順、縦横の選び方、しきい値の見せ方という設計判断と、色だけに頼らないアクセシビリティ要件を解説する。

2026年8月27日
18

Donut Chart(ドーナツチャート)

中央をくり抜いた円で構成比を示すチャート。中央に置く値の選び方、円グラフとの使い分け、リングの太さ、凡例の作りという設計判断と、色だけに頼らないアクセシビリティ要件を解説する。

2026年8月27日
17

Gauge Chart(ゲージチャート)

1つの値を範囲の中に置いて示す半円のチャート。範囲の両端に意味があるかという条件、しきい値の帯の設計、色だけで良否を伝えない書き方という設計判断とアクセシビリティ要件を解説する。

2026年8月27日
16

もっと深く知りたいですか?

ここに掲載されていないトピックについても、リクエストがあれば解説記事を追加します。 わかりにくい点や、具体的な事例について知りたいことがあれば教えてください。

リクエストを送る