CSSのfocus-within擬似クラスを使った要素のデザイン


昨今のWebサイトのフォームデザインでは、UXの面でユーザーにストレスなくわかりやすいデザインが求められます。
ラベルや入力フィールドをグループ化したレイアウトからプレースホルダテキスト、ヘルプテキスト、エラー表示などなど、フォームのデザイン設計はユーザビリティの確保が重要です。

今回は、フォームデザインで使えそうな、CSSの:focus-within疑似クラスをご紹介します。

:focus-within疑似クラスを利用することで、入力フィールドにフォーカスがある時にフォーム全体を強調させて、ユーザーにわかりやすいデザインに変更することができます。

今までよくみたことがある:focus擬似クラスは、フォーカスされた要素を表すもので、フォーカスを持った要素に対してスタイルを指定していきますが、親要素を含めたデザインのコントロールまではできません。

:focus-within疑似クラスは、フォーカスを持っているか、フォーカスを持った要素を含む要素を表します。
子要素に:focus擬似クラスに該当する要素がある時に、:focus-within疑似クラスを利用して、親要素のデザインを変更することができます。

JavaScriptなどのプログラムを使えばできないことはないですが、CSSだけでも実装できるということです。

気になるWebブラウザの対応状況ですが、IE以外の主要ブラウザはほとんど対応しています。

Can I use(:focus-within)
https://caniuse.com/#search=focus-within

それでは、どのように利用していくのか見ていきましょう。


:focus-within擬似クラスの利用


簡単なアンケートフォームをサンプルに説明していきます。
:focus-within擬似クラスのお話ですので、ここではformのアクション、送信ボタンやその他の動きには触れません。

まずはHTMLから。

HTML

Questionnaire




Q1 : What was the main reason for choosing our product? (Check all that apply.)



Q2 : How did you find out about our product?





HTMLでは、ニックネームとメールアドレスのブロックと質問ブロックにグルーピングして構築しました。

ここからCSSの:focus-within擬似クラスを利用して、input要素のフォーカス時に対象の親要素のブロックのデザインを変更してみます。

CSS
h2 {
  text-align: center;
  margin: 20px 0;
}

form {
  width: 94%;
  max-width: 800px;
  margin: auto;
  background: #f7f7f7;
}

form > div {
  padding: 20px 4%;
}

form > div:focus-within {
  background: #ffb99e;
  padding: 20px 4%;
}



input要素の親要素のdivに対して、:focus-within擬似クラスでフォーカスを持った要素がある時にスタイルを適応させます。フォーカスを持っていない親要素のdivには適応されません。

以下、実際の挙動になります。

:focus-within擬似クラスを利用したフォームのデザイン



擬似クラスの確認は、デベロッパーツールのアクション擬似クラスの設定から確認することができます。

デベロッパーツールでのアクション擬似クラスの確認



:focus-withinはとても便利な擬似クラスですが、macOSのFirefoxとSafariでは注意が必要です。
要素がクリックや選択された際のフォーカスが、ブラウザによって異なります。
WindowsではGoogle Chrome、Firefox、Microsoft Edgeでフォーカスが動作しますが、macOSのFirefoxとSafariでは、button要素のほかフォームパーツのラジオボタンやチェックボックスで要素のフォーカスがされません。

この問題は、JavaScriptなどのプログラミングで、focusイベントやblurイベントを取り扱う時にも注意が必要です。


テキストボックス、テキストエリア、ドロップダウンメニュー、リストボックス、パスワードボックスでは、Windows PC、Macともにフォーカスが動作しますので、:focus-within擬似クラスが利用可能です。

ブラウザの挙動によって変わってしまうので、フォーカスする要素はどれか、今回のサンプルの場合だとフォーム部品に何を利用するかで考えていく必要がありますね。

多くのWebブラウザで利用できるようになった:focus-within擬似クラス、是非使ってみてください。