COLUMN コラム
2023.12.4
【CSS】すぐに使いたい便利なコンテナクエリ、疑似セレクタの紹介
昨年、Internet Explorerのサポートも終了となり、CSSの進化はより早く便利な機能が追加されています。新たに追加されたプロパティは調べれば簡単に取り入れることができますが、クエリや疑似クラスといったものは仕組みをきちんと理解しないと、すぐに取り入れることは難しいですよね。今回は知れば使いたくなる便利なコンテナクエリや疑似クラスについて紹介します。
1. コンテナクエリ「@container」
コンテナクエリ(@container)は、メディアクエリに代わる新たなレスポンシブ対応の設定方法です。これまでのレスポンシブ対応は、@media でウィンドウサイズを基準に設定していましたが、@containerでは、任意の要素のサイズを基準に設定することができるようになります。
今までのメディアクエリで何が問題なの?と思う人もいるかもしれませんが、FLOCSSなどコンポーネントを作成して開発している時などは非常に便利です。
例えば、ボタンや見出しなどのコンポーネントは、置かれる場所によって横幅や文字サイズなどの調整が必要なことがあります。従来はマルチクラスでスタイルを上書きするなど対応していましたが、コンテナクエリを使用することで、置かれた要素のサイズに応じて自動で見た目を切り替えることができるようになります。
「@container」の使い方
コンテナクエリの使い方は以下の通りです。
1. どの要素を基準のコンテナにするか決める。(親要素もしくは祖先要素から選ぶ)
2. 基準のコンテナにcontainer-typeプロパティを追加する。
3. コンテナのどの方向を基準にするか決める。(通常はinline-size(幅)が基準)
4. @containerでクエリを記述する。
以下の例では600px以上になるとh1が切り替わります。
<div class="container">
<h1>リサイズしてください</h1>
</div>
.container {
//.containerを基準にする
container-type: inline-size; //方向を指定する
border: 1px solid gray;
text-align: center;
}
h1 {
color: red;
font-size: 18px;
}
@container (min-width: 600px) {
h1 {
color: green;
font-size:32px;
}
}
コンテナクエリは全ブラウザに対応しているので、安心して使用することができます。
CSS Container Queries (Size) | Can I use.
ただ、コンテナクエリは便利ではありますが、メディアクエリが不要になったというわけではないので、大きなレイアウト変更はメディアクエリ、コンポーネントなどの小さな変更はコンテナクエリなど使い分けていきましょう。
2. 疑似クラス :has( )
疑似クラス :has()は、引数で指定した要素を含んでいる親要素に対してスタイルを適用することができます。これまで子セレクタ ul > li や 子孫セレクタ ul li といったものはありましたが、子要素の有無によって親のスタイルを設定できるものはなかったため、とても便利な機能です。
「:has( )」の使い方
引数にはHTMLタグやclass、IDを指定することができます。
<!-- span要素を持つh1要素 -->
h1:has(span) {
display: flex;
}
<!-- 子要素にimg要素を持つa要素 -->
a:has(> img) {
display: block;
}
例えばリンクボタンを作成する時などは、アイコンの有無でスタイルを分けることがよくありますよね。これまで子要素が存在しない時のスタイルは、マルチクラスで設定を上書きするなどして対応してきましたが、:has( ) を使うことでクラスを追加する必要がなくなります。
<!-- アイコンなしのリンク -->
<a class="c-link" href="#">もっと見る</a>
<!-- アイコンありのリンク -->
<a class="c-link" href="#">
<span class="c-icon"></span>
もっと見る
</a>
.c-link {
/* Styles */
}
.c-link:has(.c-icon) {
/* Styles */
}
特定の要素が存在している場合のみ親要素にスタイルを適用するというケースは、ニュース記事のアイキャッチ画像の有無など、様々な所で活用することができます。ただ、現状ではFirefoxのみ非対応となっているので、実務で使用するにあたってはまだ少し注意が必要です。
3. 疑似クラス :is( )
疑似クラス:is( )は複数のセレクタをまとめて指定することができます。これまで複数の要素に同じスタイルを設定する時は対象となるセレクタをすべて書く必要があったため、コードも長くなり視認性も悪かったですよね。:is()を使用すると複数セレクタへのスタイルをシンプルに記述することができます。
「:is( )」の使い方
引数に複数のセレクタを指定することで、セレクタのいずれかと一致する要素にスタイルを適用させます。
/* 今まで */
section h1, section h2, section h3,
aside h1, aside h2, aside h3 {}
/* :isを使用 */
:is(section, aside) :is(h1, h2, h3) {}
例えば規約ページ等を作成する際はリストが入れ子になることがよくあります。リストの入れ子のスタイル設定は見づらくなりがちですが、:is( )を使って指定すると見やすくなります。
ol {
color: blue;
}
:is(ol, ul) :is(ol, ul) {
color: green;
}
:is(ol, ul) :is(ol, ul) ol {
color: red;
}
:is()を使用する際の注意として、:is()の詳細度は引数に指定したセレクタのうち最も高いものになる、という点があります。例えば下記のような指定をした場合、(#feature, .c-title, h1)の中で一番詳細度が高いのはIDセレクタの「#feature」になります(1. 0. 0)。「span」は要素型セレクタなので詳細度は(0. 0. 1)となり、:is()の詳細度は(1. 0. 1)となります。
/* 詳細度 (1.0.1) */
:is(#feature, .c-title, h1) > span {
color: blue;
}
/* 詳細度 (0.1.2)なのでスタイルを上書きできない */
p.c-title > span {
color: red;
}
詳細度が高くなりすぎてしまうと、あとでスタイルを上書きすることができず、CSSの拡張性が失われてしまうので注意しましょう。(詳細度を上げたくない場合は:where()を使用する方法もあります)
おわりに
今回は知れば使いたくなる便利なコンテナクエリ、疑似クラスについて紹介しました。
仕組みをきちんと理解するのは少し大変ですが、一度理解できてしまえば記述するコードを減らせたり、クラスを追加する必要がなくなるなど、大幅な業務効率アップに繋がります。まだ一部ブラウザに対応していないものもありますが、今後使えるようになってくると思いますのでしっかりチェックしておきましょう。