デベロッパー フィードバックのリクエスト: カスタマイズ可能な選択

<select> 要素などのフォーム コントロールのスタイル設定は、長年にわたりデベロッパーにとって最大の課題として報告されており、Google はその解決策に取り組んできました。この作業は複雑で、正しく行うには時間がかかりますが、この機能のリリースは間近に迫っています。カスタマイズ可能なバージョンの select 要素は、WHATWG で正式にステージ 2 に入っています。クロスブラウザでの関心が高く、Chrome Canary 130 からテストできるプロトタイプが用意されています。

ぜひお試しになり、フィードバックをお寄せください

インストールされている Chrome Canary がバージョン 130 に更新されていること、試験運用版のウェブ プラットフォーム機能のフィーチャー トグルがオンになっていることを確認します。このフラグを有効にするには、アドレスバーに「chrome://flags」と入力して #experimental-web-platform-features を有効にします。その後、この投稿の Codepen デモが表示されます。または、こちらの Codepen コレクションで、すべてを 1 か所で確認することもできます。

この機能に関するフィードバックを送信するには、こちらのフォームをご利用ください。所要時間は 3 分ほどです。

既存の HTML select タグをベースに構築された、カスタマイズ可能な select API の機能について詳しく見ていきましょう。

新しい <select> を有効にする

新しい動作を有効にするには、ページ内の選択ボタンと選択ピッカーの両方で CSS の appearance プロパティを使用します。オプトインするには、<select> 要素と ::picker(select) で appearance: base-select を設定します。

::picker(select) は、ユーザー エージェントが提供する新しい疑似要素です。appearance: base-select を使用して新しい動作を有効にした <select> 要素にのみ適用されます。この選択ツールの疑似要素は、ベースの選択ボタンによってトリガーされるポップオーバーです。次のコードに示すように、両方をオプトインできます。

select,
::picker(select) {
  appearance: base-select;
}

ページ内ボタンのみを有効にすることはできますが、ページ内ボタンを有効にせずに選択ツールのポップオーバーのみを有効にすることはできません。::picker(select) は、appearance: base-select が <select> に適用された後にのみ作成されます。

これで、select 要素をカスタマイズする準備が整いました。新しいカスタマイズ可能な select には、ブラウザやオペレーティング システム間で同じように見えるデフォルトのスタイルがいくつか用意されています。macOS の Chrome の既存の選択要素と、デフォルトのカスタマイズされた選択要素を比較すると、次のようになります。

右側のカスタマイズ可能な選択要素のデフォルトのユーザー エージェント スタイル。これは変更される可能性があります。ぜひフィードバックをお寄せください。
基本的な選択とカスタマイズ可能な選択のデモ。

部品の分解

選択の各部分を示す図。

新しいカスタマイズ可能な選択モードに移行すると、次の新しい要素にアクセスできるようになります。 - selectedoption: 現在選択されているオプションの内部 HTML を反映します。 - option::before: 現在選択されているオプションをデフォルトのユーザー補助アフォーダンスとして示すチェックマークが含まれています(変更される可能性があります)。 - ::picker(select): カスタマイズ可能な選択要素内の button の外側にあるすべてのコンテンツを含むポップオーバー。

選択した部分のスタイルを設定できます。たとえば、<option> 要素内に任意の非インタラクティブなコンテンツを追加したり、選択プルダウンを開くページ内ボタンのスタイルを設定したり、オプションのプルダウン リスト(::picker(select))のスタイルを設定したりできます。

button のスタイルを設定したり、独自の矢印インジケーターを使用したり、任意の要素内やその周囲に任意のコンテンツを追加したりすることもできます。コンテンツを追加するだけでなく、これらの新しい要素やデフォルトのスタイルを非表示にすることもできます。たとえば、オプションの ::before 疑似要素にインジケーターのチェックマークを表示しない場合は、次の CSS を使用します。

/* Remove the default checkmark from the selected option */
option::before {
 display: none;
}

選択要素内には無制限の数の要素を含めることができますが、ブラウザは <button> 要素外のものを ::picker(select) 疑似要素にバケット化します。これは、ボタンにアンカーされたポップオーバーとして動作します。この <button> は ::picker(select) を切り替えます。選択要素内のオプションやその他の要素は ::picker(select) にホイスティングされます。また、スタイル設定のために独自のラッパーを使用することもできます。このラッパーも ::picker(select) 疑似要素内に配置されます。

<select>
  <button>
    <selectedoption></selectedoption>
  </button>
  // Everything else that will go into the ::picker(select) popover
</select>

新しいカスタマイズ可能な <select> は、ポップオーバーとアンカーの配置の機能を使用します。これは、次の 2 つの基盤となるテクノロジーで構築されています。つまり、select 内のプルダウン オプション リストは、select を開くトリガーボタンに固定されたポップオーバーとして機能します。

アンカー ポジショニングを使用すると、この ::picker(select) ポップオーバーのスタイルを設定できます(他の要素にアンカーすることもできます)。このコンテンツ モデルは、最上位レイヤのアニメーション スタイルがオプション リストと連携して、開始効果と終了効果をアニメーション化することも意味します。

既存の <select> 要素を拡張する

以前、Chrome チームは <selectlist> 要素のアイデアに取り組んでいました。この投稿で説明しているのは、既存の <select> 要素を再利用するように再設計された機能です。

既存の <select> 要素を再利用する主なメリットの一つは、簡易 HTML 要素をプログレッシブ エンハンスメントできることです。新しい要素と比較すると、<select> を再利用しても、ページに意味のあるコンテンツがレンダリングされます。次の例は、カスタマイズされた選択と、サポートされていないブラウザのユーザーに表示される内容を示しています。

option 内のすべてのテキスト コンテンツは、select 要素の代替バージョンでレンダリングされます。

基本的なスタイル設定

変更は、選択要素の視覚的なスタイル設定のように単純な場合もあります。たとえば、ボタンのスタイル、ホバーとフォーカスのスタイル、選択オプションの背景を更新します。appearance: base-select でオプトインした後、選択した部分に任意の CSS を適用します。

デフォルトのボタンを使用して、選択のさまざまな部分のスタイルを変更します。

矢印インジケーターをカスタマイズするには、選択範囲内に独自のボタンと矢印を追加します。

<select>
  <button>
    <selectedoption></selectedoption>
    <span>
      // Arrow here
    </span>
  </button>
  // Everything else that will go into the ::picker(select) popover
</select>

次に、矢印のスタイルを設定します。

/* style the arrow */
button span {
  /* arrow styles */
  transition: rotate 0.2s;
}

/* adjust arrow styles when the picker is open */
select:open button span {
  rotate: -180deg;
}

オプション内の複雑なコンテンツ

<select> 内の <option> 要素内の文字列以外のコンテンツを追加してスタイルを設定する機能により、さらに高度な処理を行うことができます。基本的な例としては、プルダウン メニューの国名の横に国旗の画像を追加することが挙げられます。これを実現するには、オプション テキストの横に画像要素を追加します。

<option value="france">
  <img src="img/flag_of_france.svg" alt="" />
  <span>France</span>
</option>
国旗付きの国選択ツール。

より複雑な例としては、プロフィール写真、名前、代替情報などを含めて、プルダウンで選択する項目を判断しやすくすることができます。

<option value="eur">
    <img src="euro-flag.png" alt="" />
    <div class="currency">
      <div class="currency-short">EUR</div>
      <div class="currency-long">Euro</div>
    </div>
    <div class="symbol" aria-hidden="true">€</div>
</option>
通貨選択ツールのスクリーンショット。

選択したオプションのスタイルを設定する

選択したオプションを、プルダウンとは異なる状態で表示したい場合があります。たとえば、Gmail の UI では、スペースを節約するために、オプションを選択するとラベルが削除されます。これを行うには、スタイル設定用の <selectedoption> 要素にフックします。<option> には、次のマークアップがすべて含まれています。

 <option value="reply-all">
    <img class="material-symbol"  src="material-symbol-reply.png">
    <span class="text">Reply all</span>
  </option>

次に、<selectedoption> 内の .text に display: none を適用して、テキスト コンテンツを非表示にし、アイコンのみを表示します。

selectedoption .text {
  display: none;
}
Gmail スタイルの選択。選択したオプションを表すアイコンが表示されます。

インタラクティブ オプション

::picker(select) のスタイル設定を完全に制御できるため、前のデモを基に、ホバーとフォーカスでインタラクティブに動作するようにします。このデモでは、新しい calc-size() 関数を使用して、ホバー時または選択に focus-visible のオプションがある場合に、アイコンの表示からオプションの全幅の表示にピッカーの幅をアニメーション化しています。

/* base styles when picker is open but not interacted with */
::picker(select) {
  width: var(--icon-width);
  transition: width 0.5s;
}

/* animate the text in on hover & focus */
::picker(select):hover,
select:has(option:focus-visible)::picker(select) {
  /*  auto width!  */
  width: calc-size(auto, size + 0.5rem);
}
Gmail スタイルのインタラクティブな選択。ホバーまたはフォーカス時にコンテンツが段階的に表示されます。

制限事項とユーザー補助に関する注意事項

優れた性能には、大きな責任が伴います。この機能には、アクセシビリティを維持するための制限がいくつかあります。

  • <option> 要素以外に、<select> 内でインタラクティブな(フォーカス可能な)要素(ボタンなど)はまだ許可されていません。現時点では、提案されたコンテンツ モデルで許可されているのは、<div>、<span>、<option>、<optgroup>、<img>、<svg>、<hr> の各要素のみです。
  • スプリット ボタンは、ユーザー補助ソリューションを開発中のため、現在試験運用段階です。

今後、これらのエクスペリエンスのユーザー補助機能が具体化されるにつれて、コンテンツ モデルはより柔軟に拡張されることが期待されます。

まとめ

Google は、この機能がワーキング グループや標準化団体を通じて進展していくことを期待しています。また、プロトタイプを積極的に構築し、この機能の形状を評価しながら、進捗状況を共有していきます。期待どおりに動作しない場合は、お知らせください。

この機能はまだ開発中ですが、こちらの簡単なフィードバック フォームからフィードバックをお寄せいただければ幸いです。

ウェブ上でアクセスしやすく、カスタマイズ可能なフォーム コントロールを簡単に構築できるように、この取り組みにご協力いただきありがとうございます。