これは、私が解決してきた問題に対する最新のCSSソリューションを検証するシリーズのエピソード#20です。フロントエンド開発者としての過去13年以上。
最新のCSSは、ほぼ同一のカスタム選択スタイルを実現するためのさまざまなプロパティを提供します。上位のブラウザ全体での単一、複数、および無効なselect
要素の初期外観。
ソリューションで使用するいくつかのプロパティと手法:
-
clip-path
カスタムドロップダウン矢印を作成する - ネイティブの選択と矢印を揃えるCSSグリッドレイアウト
- カスタムCSS変数柔軟なスタイリング
-
em
相対サイズ設定用ユニット
ネイティブ選択に関する一般的な問題#
すべてのフォームフィールドタイプと同様に、<select>
はブラウザによって初期の外観が異なります。
左から右に、Firefox、Chrome、Safariでの<select>
の最初の外観は次のとおりです。
違いには、ボックスサイズ、フォントサイズ、行の高さが含まれます。最も目立つのは、ドロップダウンインジケーターのスタイルの違いです。
目標は、複数の選択と無効な状態を含め、これらのブラウザ間で同じ初期外観を作成することです。
注:ドロップダウンリストはまだスタイル設定できません。そのため、
<select>
を開くと、option
リストの個々のブラウザのスタイルが引き続き取得されます。これは問題ありません。ネイティブセレクトの無料のアクセシビリティを維持するために対処できます!
ベースHTML#
We “まず、単一の<select>
に焦点を当てます。
ラベルはスタイリング演習の一部ではありませんが、一般的な要件として、特にivに含まれています。 <select>
のid
の値を持つid = “c5b12787e0”> 属性。
カスタムスタイルを実現するために、このチュートリアルでは簡単にするために、ネイティブ選択をselect
のクラスを持つ追加のdivでラップしました。
継承されたスタイルのリセットと削除#
最新のベストプラクティスとしてすべてのチュートリアルに含まれているため、最初に次のリセットを追加します。
その後、ネイティブのselect
のルールを開始し、以下を適用して外観を休めることができます。
これらのほとんどはよく知られていると思われますが、奇妙な結果は
。これはめったに使用されないプロパティであり、サポートのために必要な場所ではないことに注意してください。ただし、この場合に主に提供されるのは、ネイティブブラウザのドロップダウン矢印の削除です。
注:CodePenは、
appearance
プロパティの必要な事前修正バージョンを追加する自動プレフィックスを使用するように設定されています。プロジェクト用に特別に設定するか、手動で追加する必要がある場合があります。私のHTML / Sass Jumpstartには、本番ビルドの一部として自動プレフィックスが含まれています。
幸いなことに、必要に応じて、IEの下位バージョンの矢印を削除するルールをもう1つ追加できます。
このヒントは選択したスタイルを作成するための代替方法を示すフィラメントグループの優れた記事。
最後の部分は、デフォルトのoutline
を削除することです。「心配しないでください-私たち」後で:focus
状態!
そしてここに私たちの進歩のgifがあります。クリックする前に、これがselect
であることを示す視覚的な表示がゼロになっていることがわかります:
カスタム選択ボックススタイル#
まず、いくつかのCSS変数を設定しましょう。これにより、エラー状態を表すなど、選択の色を柔軟に変更できます。
アクセシビリティに関する注意:ユーザーインターフェイス要素として、選択境界線は3:1のコントラストまたは周囲の表面の色に対して大きくなります。
次に、ラッピングに適用するカスタム選択スタイルを作成しますdiv.select
:
最初に、いくつかの幅の制約を設定します。 min-width
とmax-width
の値は主にこのデモ用であり、ユースケースに合わせて削除または変更することができます。
次に、border
、border-radius
、padding
。 em
ユニットを使用すると、これらのプロパティが設定されたfont-size
に比例することに注意してください。
リセットスタイルでは、いくつかのプロパティをinherit
に設定しているため、ここではfont-size
などのプロパティを定義します。 cursor
、およびline-height
。
最後に、わずかな部分のグラデーションなど、背景プロパティを提供します。寸法。背景のプロパティを削除すると、選択範囲が透明になり、ページの背景が表示されます。これは望ましい場合がありますが、コントラストへの影響に注意してテストしてください。
進捗状況は次のとおりです:
カスタムドロップダウン矢印#を選択します。
ドロップダウン矢印には、最もエキサイティングな最新のCSSプロパティの1つであるclip-path
を使用します。
クリップパスを使用すると、ほとんどの要素からデフォルトとして受け取る正方形や長方形の形状を「クリップ」することで、あらゆる種類の形状を作成できます。最近のポートフォリオサイトの再設計でclip-path
を使用して楽しんでいました。
clip-path
のサポートが改善される前は、代替方法が含まれていました:
-
background-image
-通常はpngですが、もう少し現代的なのはSVGです - 追加要素としてのインラインSVG
- 三角形を作成するための境界トリック
SVGは最適なソリューションのように感じるかもしれませんが、background-image
として使用すると、できないという意味でアイコンのように機能しなくなります。 o完全に再定義せずに、塗りつぶしの色などのプロパティを変更します。これは、CSSカスタム変数を使用できないことを意味します。
SVGをインラインに配置すると、fill
の色の問題が解決されますが、
が定義されています。
clip-path
を使用すると、SVGのように感じられる、くっきりとしたスケーラブルな矢印「グラフィック」が得られます。カスタム変数を使用でき、スタイルとHTMLマークアップに含まれるという利点があります。
矢印を作成するために、矢印を::after
疑似要素。
clip-path
の構文は少し奇妙です。この記事の焦点ではありませんが、次のリソースをお勧めします。
- Colby Fayockが、このエッグヘッドビデオの例で構文を説明します。
- Clippyは、
clip-path
CSS
を動的に生成しながら、形状を選択してポイントを調整します。 width
とheight
を定義しているにもかかわらず、矢印が表示されていないことに気付いたかもしれません。調べたところ、::after
が実際にはその幅を許可されていないことがわかりました。
はCSSグリッドレイアウトを使用します。
これにより、矢印を「ブロック」に似た表示値に拡張することで、矢印を表示できます。
この段階で、実際に三角形を作成したことを確認できます。
配置を修正するには、私たちのお気に入りのCSSグリッドハックを使用します(このあたりの記事をいくつか読んだことがあるなら、古い帽子です!)。
古いCSSソリューション:position: absolute
新しいCSSソリューション:すべてを含む単一のgrid-template-areas
最初に領域を定義し、次にselect
と::after
の両方で使用されます。名前のスコープは作成された要素であり、「select」と呼ぶことで簡単にできます。
これにより、ソース順序によるスタッキングコンテキストによるネイティブ選択の上の矢印:
グリッドプロパティを使用して、配置を確定できるようになりました各要素の:
Ta-da!
:focus State#
そうですね-outline
を削除した方法を覚えていますか?不足している:focus
状態を削除します。
:focus-within
と呼ばれる次のプロパティを使用できますが、これにはポリフィルを含めるのが最善です。時間。
このチュートリアルでは、同じ結果を得る別の方法を使用しますが、少しだけ重いです。
残念ながら、これは、要素をもう1つ追加する必要があることを意味します。 DOM。
ネイティブのselect要素の後、最後として.select
内の子、追加:
なぜですか?これは純粋なCSSソリューションであるため、ネイティブselectの後に配置すると、隣接する兄弟セレクターを使用してselect
がフォーカスされたときに変更できることを意味します-+
。
これにより、次のルールを作成できます。
なぜposition: absolute
前のgrid-area
ハックを学習した後。
その理由は、パディングに基づいて調整を再計算しないようにするためです。自分で試してみると、width
とheight
を100%に設定しても、パディング内に収まることがわかります。 。
ジョブposition: absolute
は、要素のサイズを一致させるのが最適です。境界線と重なるように、各方向に1ピクセル余分に引っ張っています。プロパティ。
ただし、.select
にもう1つ追加して、選択したものとの相対的な関係を確保する必要があります。position: relative
。
Chromeで見られるように、カスタム選択をまとめて示します。
複数の選択#
選択には2番目のフレーバーがあり、ユーザーは複数のオプションを選択できます。 HTMLの観点からは、これは単にmultiple
属性を追加することを意味しますが、select--multiple
と呼ばれるスタイル調整の作成に役立つクラスも追加します。 :
そしてそれを見ると、このビューに矢印が必要ないことを除いて、ほとんどのスタイルがうまく継承されていることがわかります。
これは、矢印を定義するセレクターを調整するための簡単な修正です。:not()
を使用して、新しく定義したクラスを除外します。
複数選択のためにいくつかの小さな調整があります。1つ目は、矢印用のスペースを確保するために以前に追加されたパディングを削除することです。
デフォルトでは、長い値のオプションは表示領域をオーバーフローしてクリップされますが、メインのブラウザーでは、必要に応じて折り返しをオーバーライドできることがわかりました。
オプションで、選択にheight
を設定してもう少し信頼性の高いクロスブラウザの動作。これをテストしたところ、ChromeとFirefoxには部分的なオプションが表示されることがわかりましたが、Safariでは完全に表示できないオプションが完全に非表示になります。
高さはネイティブセレクトで直接設定する必要があります。他のスタイルを考えると、値6rem
は3つのオプションを表示できます。
この時点で、現在のブラウザのサポートにより、可能な限り多くの調整を行いました。
:selected
の状態options
は、Chromeではかなりカスタマイズ可能ですが、Firefoxでは多少カスタマイズ可能ですが、Safariではまったくカスタマイズできません。コメントを外してこれをプレビューできるセクションについては、CodePenデモを参照してください。
:disabled Styles#
単に無効なコントロールを表示しないので、ベースをカバーするためだけにその状態のスタイルを準備する必要があります。
無効な状態を強調するために、灰色の背景を適用します。ただし、.select
に背景スタイルを設定し、:parent
セレクターがないため、処理する最後のクラスを1つ作成する必要があります。この状態:
ここでは、フィールドを操作できないことを示す追加のヒントとしてカーソルを更新し、以前に設定した背景値を更新しました。無効状態では白になり、灰色になります。
これにより、次のように表示されます。
デモ#
自分でテストできますが、ここに「Firefox、Chrome、Safari全体の(左から)完全なソリューションのプレビューがあります:
ステファニーエックルズ(@ 5t3ph)