最弱魔法が
WEBを制す
:where()
“わざと弱くする”ために作られた。
CSS史上初。

weakest_magic_conquers_the_web  key visual by Yohiichiroh Kohtani | digivalley
Toplabo
Weakest Magic Conquers The Web

この記事は『CSS革命』の続きになります。先にそちらをご覧ください。

CSS史上初、あえて最弱の魔法が誕生。:where()

 | 2026/04/12

最弱が
最強

弱いことが革命を起こす

  • これまでは如何に深くセレクタを積み重ねるかで優先度が決定していた

    最弱魔法、まるで素人小説のタイトルの様ですが、これが疑似クラス:where()の真髄です。
    括弧に内包するすべてのセレクタの優先度を無(詳細度をゼロ)にします。
    これまでのセレクタの記述方法は構造の積み重ねでした。たとえば、下記のようなHTMLがある場合

    <main>
     <section id="primary">
      <h2>CSS記述 をスリム化しつつ、管理</h2>
      <section id="contents">
       <div class="columnArea">
    
        <h3 class="first">はじ めに</h3>
        <div class="contentsRoot">文章</div>
        <h3 class="second">解説</h3>
        <div class="contentsRoot">文章</div>
        <h3 class="third">実践</h3>
        <div class="contentsRoot">文章</div>
        <h3 class="forth">コード</h3>
        <div class="contentsRoot">文章</div>
        <!-- 以下省略 -->
  • まずはCSSの設定は構造の組み込みから

    h3のスタイルを設定したい時、まず最初に複数あるh3全体のスタイルを設定します。
    その場合、他の段落や章などでもh3が使われる可能性が高いので構造の決め込みが必要になります。
    たとえば…、mainの中のsectionの中のさらにsectionの中の、って二つあるからID名がいるな…、3段コラムにしたいから.columnAreaもいるな…、という感じで下記の様なCSSを設計するわけですが

    /* CSS  */
    main section#primary section#contents .columnArea h3{
        margin: 0 0 8px 0;
        padding-bottom: 4px;
        font-size: 20px;
        font-weight: bold;
        color: #6aacfc;
        border-bottom: 1px solid #efefef;
    }
  • ちょっと変更したい

    ここで、次の二番目のh3の色や背景色を変えたくなった場合、columnAreaの中の二番目ということで下記のようにすればOKにみえますが…

    .columnArea h3.second
    {
        color: blue;
    }
  • この指定では効きません。
    最初のセレクタに詳細度で負けているからです。
    細かく設定したつもりの『second』クラス付与も効果がありません。
    この最初のセレクタを上書きするためには、それ以上のセレクタを積み重ねて、詳細度を強くしないと意図通りにスタイルが反映されません。
    下記で試してみましょう。
    それぞれセレクタの積み重ね度合いを変えてあります。

    main section#primary section#contents .columnArea h3{
        margin: 0 0 8px 0;
        padding-bottom: 4px;
        font-size: 20px;
        font-weight: bold;
        color: #6aacfc;
        border-bottom: 1px solid #efefef;
    }
    
    .columnArea h3.second{
        color: blue;
    }
    
    main section#contents h3.third{
        color: green;
    }
    
    main section#primary section#contents .columnArea h3.forth{
        color: orange;
    }
  • 構造が優先度(詳細度)を決定する

    この中で意図通りにスタイルが反映されるのは、最後のより長くセレクタを積み重ねた設定だけです。
    つまり、いったん深いセレクタの積み重ねをやってしまうと、次はもっと深く、次はもっと、と元には戻れない状況が延々と続いていきます。みなさんも身につまされますね

    CSSを積み重ねるデモ:https://labo.studio-happyvalley.com/where/nowhere/

  • 詳細度をゼロにする:where()

    そんな中現れたのが最弱魔法の:where()です。
    :where()は詳細度をゼロにします。
    下記の様に記述すると積み重ねたセレクタの塊を跡形もなく粉砕します。
    積み重なった優先度は無にしつつ、積み重ねた構造はそのまま生かします。

    :where(main section#primary section#contents .columnArea) h3{
        margin: 0 0 8px 0;
        padding-bottom: 4px;
        font-size: 20px;
        font-weight: bold;
        color: #6aacfc;
        border-bottom: 1px solid #efefef;
    }
    
    :where(.columnArea) h3.second{
        color: blue;
    }
    
    :where(.columnArea) h3.third{
        color: green;
    }
    
    :where(.columnArea) h3.forth{
        color: orange;
    }
  • :where()で構造と詳細度を分離したデモ

    :where()で構造と詳細度を分離したデモ:https://labo.studio-happyvalley.com/where/where/

    ここまで、:where()の革命的な真髄を味わっていただいたところで、いよいよ本題です。
    同時に、正しい理解のためには詳細度も理解する必要があります。次の段落より:where()と合わせて詳細度を詳しく解説します。

詳細度

詳細度とは?

  • 詳細度はCSSの優先順位の指標のひとつ。

    詳細度(Specificity)は、セレクタ同士がぶつかったときの「力関係」です。
    CSS優先度の基本はこれまで3階層でしたが新たにレイヤーが加わりました。

    1.重要度(!important など)
    2.レイヤー(@layer)
    3.詳細度(specificity)
    4書かれた順番(後勝ち)

    この3番目のルールが詳細度。

  • 詳細度の表記方法

    詳細度は以下のように( A , B , C ) と表記します。Aが一番強い。


    種類
    カウント


    IDセレクタ
    A


    クラス・属性・疑似クラス
    B


    要素・疑似要素
    C

  • 強さ

    ① 要素だけ / div { color: red; }
    → (0,0,1)
    3つの中で一番弱い

    ② クラス / .box { color: blue; }
    → (0,1,0)
    クラスは要素より強い。

    ③ ID / #main { color: green; }
    → (1,0,0)
    IDは圧倒的に強い。

  • 足し算されます。でも桁上りはしない。

    div.box#mainの場合
    → (1,1,1)

    全部合算されます。
    でも“桁上がり”はしない
    (0,10,0) は (1,0,0) には勝てません。
    ID 1個はクラス何個よりも強いのです。

  • この詳細度インフレをさらに超越するのがチート、!important

    これまではセレクタを設定する時、構造=詳細度、と強さも正比例していました。構造を詳しく設定すればするほど、詳細度が強くなり、ついには!importantというチート戦士、勇者の登場が必須となりました。
    しかし、!importantを使ったことある人ならわかると思いますが、そっちが勇者ならこっちも勇者召喚だあという、その勇者を上書きする事態も発生し、さらなる!importantのインフレが始まるという、まるでバトル漫画の強さインフレ状態となっていました。

  • 詳細度インフレに終止符を打つCSS史上初の試み

    :where()は、そんな聖剣エクスカリバー(#HolySword_Excalivur)や勇者(#BraveOne)を詳細度0のただの紙切れに帰し、
    詳細度(0,0,1)の村人でも勇者に勝てる理をもたらします。
    言い換えるならば:where()が可能にしたのは勇者も魔王も誰もが争わなくてもよい世界なのです。

    これからはスタイルの設定に好きなだけセレクタを積み重ね、構造をどれだけ長く構築しても、いつでもクラス1個だけでスタイルを変更できる、もう!importantは必要ない、そんなCSS設計が可能になりました

まとめ

構造と優先度を分離した:where()

  • @Layerと連携させると最強

    :where()は、詳細度と構造を分離できるようにしたってことが重要です。これこそが革命。
    さらに@layerなど新しい概念のCSS設計のルールが登場しています。
    しかし、この分離する概念を理解しないで、@layerに手を出すと、”もっと強いlayerを!もっと後ろにlayerを!”と、レイヤーの積み重ねインフレを起こすのが目に見えてます。
    @layerがもっとも真価を発揮するのは:where()と組み合わせた時です。
    構造と詳細度を分離するという構想のもとにレイヤー構成を設計するともはや!importantなど不要の破綻のないCSS設計が可能となります。

次回
案内

次回は:is()

  • :is()は平均率クラビアーノ的な響きの疑似クラスです。

    バッハが平均律で音楽をシステム化したって意味では:is()と通じるものがありますね(ホントか!笑)。

トリ
ビア

参考までに

  • CSS史上初といえるかどうか

    CSS史上初といえるかどうかは、以下の仕様を意図的かどうかのとらえ方にもよります。
    ユーザーエージェントスタイル(最弱)、継承(inherit)、not()も中身がカウントされない時代がありました。
    どれも意図的に強いものを弱くするというより上書き前提という仕様に思われます。

  • もう!importantは必要ない

    業務上はimportantないと困ること多いです。クライアントからのがちがちに組まれたCSSファイルとかBootstrapとか。生のタグに指定してあったりしますからね。
    また、!importantは非常に特殊で@Layerの優先度すら飛び越えますので、必要ないというよりできるだけ使わない設計にするのが最善かと思います。!importantと@Layerについても近いうちに取り上げたいと思います。

この記事の続きは『セレクタの平均律系調律師:is()。』でご覧になれます。

『最弱魔法がWEBを制す』関連のお薦め

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