CSSの擬似クラス:has()を実際に使ってみた


こんにちは。Gaji-Labo 横田です。2023年も4ヶ月が過ぎようとしています。今回は2023年から使っていきたい CSS の疑似クラス :has() を実際に使ってみた例を紹介したいと思います。

特定のコンポーネントがある時だけ親要素に余白を持たせたい

特定のページにだけ position: fixed した下部コンポーネントが出現する、カートやログイン機能を持つプロジェクトなどでよくある例です。フッターは全ページ共通ですが、 position: fixed の下部コンポーネントがあるページでは、そのコンポーネントの高さ分だけフッターに余白を作らないと、フッターの中身が fixed のコンポーネントに隠れてしまいます。

下部固定のボタンコンポーネントでコピーライトが隠れてしまう

このような例はこれまで CSS だけで完結できませんでしたが has() を使えば CSS だけでスタイルの分岐が可能ですね。

.button {
  position: fixed;
  bottom: 0;
  width: 100%;
  ... //省略
}

.footer {
  ... //省略
  padding-bottom: 3.0rem;
}

body:has(.button) .footer {
  padding-bottom: 5.0rem;
}

特定の擬似クラスがある時だけ親要素の見た目を切り替えたい

select 要素のカスタマイズで、invalid 擬似クラスによって見た目を切り替えたい例です。select 要素自体には擬似要素を指定できないため、 div を親要素にしてスタイリングすることがありますね。そんな時、子要素である select 要素が invalid な時に、親要素の div の見た目を変更したくなります。

プレスホルダーテキストの時はグレー、選択肢を選んだ時は黒色にしたい
<div class="select-parent">
    <select name="" id="" class="select" required>
        <option value="">プレスホルダーテキスト</option>
        <option value="A">選択肢A</option>
        <option value="B">選択肢B</option>
    </select>
</div>

div.select-parent {
  ... //省略
  background: url("arrow-black.png") no-repeat
    calc(100% - 20px) center;
  background-size: 12px 6px;

  &:has(.select-item:invalid) {
    background-image: url("arrow-gray.png");
  }
}

select.select {
  ... //省略
  appearance: none;

  &:invalid {
    ... //省略
  }
}

select 要素に required 属性がつく時、option 要素の値が空だと invalid になります。それを利用して option 要素の1つ目をプレスホルダーとして has() を使い、親 div の背景画像の矢印を切り替えることができます。

擬似要素はhas() から除外される

ただし、has() は擬似要素、::before::after を除外するので注意です。上記の例で言うと、div.select-parent::after:has() が使えません。

 Pseudo-elements are generally excluded from :has() because many of them exist conditionally, based on the styling of their ancestors, so allowing these to be queried by :has() would introduce cycles.

https://drafts.csswg.org/selectors/#has-pseudo

とはいえ、これまでは JS などでクラス付与などしていたものが CSS だけで完結させられるので、実装コストも下がりますね。PCブラウザを考慮しないで済む要件では、引き続き積極的に実践で使用していきたいです。

開発のお悩み、フロントエンドから解決しませんか?

あなたのチームのお悩みはなんですか?

「バックエンドエンジニアにフロントエンドまで任せてしまっている」
「デザイナーに主業務以外も任せてしまっている」
「すべての手が足りず細かいことまで手が回らない」

役割や領域を適切に捉えてカバーし、チーム全体の生産性と品質をアップするお手伝いをします。
フロントエンド開発に関わるお困りごとがあれば、まずは一度お気軽に Gaji-Labo にお声がけください。

オンラインでのヒアリングとフルリモートでのプロセス支援に対応しています。

リモートワーク対応のパートナーをお探しの場合もぜひ弊社にお問い合わせください!

お悩み相談はこちらから!

タグ


投稿者 Yokota Tomoko

運用やアクセシビリティに配慮したHTML/CSSの設計やコンポーネント作成、スタイルガイドの構築、コードレビュー、組み込み、要件の整理、社内進行管理、顧客とのコミュニケーションまで、ジョインしたチームを前に進めるためにあれこれ担当しています。子育てと仕事のバランスを楽しめるよう、日々模索しています。