:has()疑似クラスで
レイヤーの重なりを
自在に制御する
CSSだけでz-indexを
自在に制御可能に

controlling_layer_overlap_with_css_has  key visual by Yohiichiroh Kohtani | digivalley
Toplabo
Controlling Layer Overlap With CSS Has

この記事は『レイヤーの重なりを制御する』の続きになります。先にそちらをご覧ください。

Z-indexの自在な制御が:has()疑似クラスで可能に

 | 2026/06/21

概要

CSS革命の余波はZ-indexにも及んでいる

  • 4年前はまだ:has()疑似クラスがなかった
    4年前に『レイヤーの重なりを制御する』で当時のCSSでは不可能だった親のz-index値をJSで超える方法を紹介した。
    しかし、2026年の現在は:has()疑似クラスがある。
    :has()を使えばJSを使わずとも、簡単に親のz-indexを変えることができるようになった。
  • :has()疑似クラスの改修案の紹介の前に、前回の概要をざっとご説明。
    初心のころによく遭遇するのが、z-indexの数値を大きくしているのに、なぜかある要素の下になって隠れてしまうケース。これは先祖をたどっていくと分かるのだが問題の要素の親が、超えられない要素の親にz-index値で負けているんだよね。4年前までは親のスタイルを変更する方法が無かったので、JSで解決する方法を紹介したのが前回。
    それが:has()疑似クラスであっというまに解決しちゃった!

実践

ではさっそく、:has()で劇的に改修する方法を紹介

  • :has()が優秀すぎて1行で解決
    改修といっても一行追加するだけ。
    脚注を表示したいa要素の直系の親(.textcontents)に次を記述するだけ。
    <!-- HTML -->
    <div class="textcontents ">
      <p>....詩が生れて、<a href="#" class="bubble top">画が出来る...(以下省略)</a></p>
    </div>
    
    <!-- CSS -->
    .textcontents:has(a:hover){
    z-index: 2;
    }
    /* 
     * ↑このCSSを追加する 
     * 意味は.textcontents(自分)の子孫のa要素がhover状態になったら自分をz-index: 2にしろ!
     * という意味
     * このデモではz-index値を2としているけど、他の要素が2より大きければ、
     * それより大きい値3以上を指定する必要があるのはいうまでもない。
     */
  • 解説を・・・
    コード内にもコメントいれてるけどこれは、.textcontents(自分)の子孫のa要素がhover状態になったら自分をz-index: 2にしろ!という意味ね。
    これまでJSで10行ほど記述する必要があったのが:has()疑似クラスのおかげで1行ですんじゃった。すごい!
    :has()疑似クラスでz-indexを制御するデモ:https://labo.studio-happyvalley.com/zindex/hasclass/
  • :hoverはOK,ではクリックは?
    デモはマウスオーバーだけど、クリックとどっちがいいかな?クリックだと開いたポップアップを閉じないといけない。マウスオーバーだと、マウスを外せば自動的に閉じるので、面倒がない。なので、クリックが特に必要というわけでもない。そもそも、クリックされた状態を保つ手段がCSSにはない。
    少なくともアンカー要素に対しては方法はない。が、他の要素を使うと可能になる(驚)。
    次の章では目的に応じた機能の実装を解説。

原点
回帰

脚注のポップアップウインドウがそもそもの発端

  • そもそも何のためにz-indexを制御したかった?
    JSでなければ解決しなかった親のz-indexの変更を、CSSだけで簡単に変更することができた。
    が、そもそも何のためにこんなデモを作ったか?これはようするに脚注。
    通常の文章で分かりにくい単語や、説明が必要なワードが発生することがよくある。一緒に説明文も入れたいけど、そうすると文章の流れが止まってしまって、言いたいことが曖昧になってしまう。そういうときだね。この手法で説明文を入れると、文章の流れを変えずに、詳しい解説も一緒にできる。
  • 次はJSも:has()疑似クラスも使わない脚注のデモ
    これまではポップアップを上下に表示させていたから、親同士のレイヤー階層で負けると子のポップアップも隠れてしまった。
    しかし、実践的に考えてみると、ポップアップをこれまでのように上下に表示させないで、上にだけ表示させるようにすればそもそもJSも:has()も必要ない。
    わざわざポップアップを上下に表示させ、z-indexの問題をあえて発生させたのは、超えられないz-indexの限界をいかに超えるか、解決するかという技術的な探求が一番。
    できないことがあるとクリエイティブの幅が狭まるからね。
    つまり、これができないからこのデザインは無理!という不安要素をを無くしたいというのがある。

    それはさておき、以下はJSもhas()も使わないでafter疑似要素だけで脚注を実装するデモ
    JSもhas()も使わないでafter疑似要素だけで脚注を実装するデモ:https://labo.studio-happyvalley.com/zindex/footnote/
  • after疑似要素なので制約がある
    簡単な脚注だったら上のサンプルでOKなんだけど、after疑似要素を使っている関係で、脚注の数だけ、after疑似要素を準備する必要があり、スマートじゃない。
    下記のコードを参照。
    また、説明文は::after疑似要素で表示しているんで、それほど長い文章は考慮してない。文章が長いと改行などが必要になるけど、そういうことはできない。
    なのでもっと大量の文章を入れる場合は他の方法ということになる。
    /* 脚注で表示する文言をいちいち記述する必要がある
     * また長い文章も入れづらく、改行もできない
     */
    
    a.bubble.foot1:hover:before{
    	content :'画ができるの解説';
    }
    
    a.bubble.foot2:hover:before{
    	content :'とかくに人の世は住みにくいの解説';
    }
    
    a.bubble.foot3:hover:before{
    	content :'どこへ越してもの解説';
    }
    
    /* デモのコードをみてね */

ひとつ
上を
目指す

attr()関数、details要素を使うともっと自由な脚注が実装可能に

  • attr()関数を使うともっとシンプルに記述できる
    前章のデモ『JSもhas()も使わないでafter疑似要素だけで脚注を実装するデモ』の場合、これにattr()関数を使うと変数のような使い道が可能になり、シンプルにスッキリ記述できる。
    つまりくどくど、脚注ごとにafter疑似要素をを作る必要がなくなる。
    <!-- CSS -->
    a.bubble:before
     {
      content :attr(data-text);
    }
    
    <!-- HTML -->
    <a data-text="画ができるの解説" href="#" class="bubble">画が出来る</a>
  • detailsを使うともっと脚注が自由に
    見出しや改行のある多めの文章や、クリックにも対応した脚注を実装するのに最適なのは、details要素とsummary要素。
    この二つを使うと実装可能になる。
    ただし、これを進めるとこのページのテーマ『z-indexを自在に制御する』から外れてしまう。
    なので新たにテーマを『WEBの遺跡発掘で甦る古代CSS魔法』と設け、折を見て解説する。

この記事の続きはWEB遺跡の聖櫃発掘で甦る古代WEB魔法でご覧になれます。

『:has()疑似クラスでレイヤーの重なりを自在に制御する』関連のお薦め

このサイトで紹介しているコード、プログラムなどは個人の学習目的で作成されたものであり、いかなる保証も行いません。
利用はすべて自己責任でお願いします。
ただし、このページで紹介しているプログラムやビジュアルなどはご依頼いただければ実装を賜ります。
お問い合わせはこちら