セレクタの
平均律系調律師
:is()。
:is()はCSSセレクタを
均一に調律する
疑似クラス

well-tempered_css_selectors  key visual by Yohiichiroh Kohtani | digivalley
Toplabo
Average Tuner Of Css Selectors

この記事は『最弱魔法がWEBを制す』の続きになります。先にそちらをご覧ください。

:is()は:where()や自身を入れ子にすることで真価を発揮する、平均律の調律師

 | 2026/04/22

はじ
めに

平均律は音楽の調律法

  • 現代の標準調律

    現在、音階って均等に割り振られてるよね。私はギターをやってたから、その感覚は特に強くて、例えばCからC♭への転調もフレットをずらすだけで簡単にできる。
    鍵盤やってる人はその辺がちょっと違うみたいだね。ギターだと運指が全く同じでいいけど、鍵盤は全く違ってくるからね。
    この1オクターブを12で均等に割ってるシステムを、12等分平均律とも呼ぶらしい。

  • バッハの時代の調律

    調べたところ、バッハの時代は、調によって音階がバラバラだったらしい。純正律と呼ぶらしいけど、和音(ドとソ)をベースに調律していくと、12回繰り返して一周回ったとき、元の「ド」とわずかにズレてしまうんだって。1オクターブの間隔は決まっているからね。
    このためハ長調はとても美しく響いても、離れた調ではひどく和音が歪んでしまうらしい。つまり当時はハ長調さえ綺麗だったら、教会の演奏さえ美しければ、他の調はどうでもいいじゃんってことだったらしい。

  • バッハの平均律

    それをバッハはどの調でも美しく弾けるんだよってコンセプトですべての調の作品を作ったってことなんだよね。
    バッハがキーボード奏者ということもあって、特に簡単に転調できないのが苦痛だったんじゃないかな。と思う💦。バイオリンだとフレットで音階を決めてないから、演奏者次第で、調の間隔の違いに対応できるからね。
    といってもクラビーア曲集のバッハの調律は現代の12等分平均律とも違っていて、調によって音の間隔が微妙に違がっているそうだ。
    また、それだけじゃなくて、「ハ長調は澄んでいて穏やか」「嬰ヘ長調は少し緊張感がある」のように調に対してのイメージがそれぞれ違っていて、その調ごとのニュアンスの違いを作品にも反映させているそうだ。今とは全然違うね。

  • 下記はその違いリスト


    特徴
    現代のピアノ(12等分)
    バッハの時代の「平均律」


    音の間隔
    すべて完全に同じ
    微妙に異なる(不等分)


    調の個性
    理論上は存在しない(無機的)
    調によって明るさや緊張感が違う


    和音の響き
    全体的に平均的な濁りがある
    よく使う調は美しく、遠い調は刺激的


    と、これがバッハの平均律クラビーア曲集の概要ね。

では、肝心の平均律セレクタ:is()はどんなの

  • セレクタの平均律:is()

    :is()は、グループ化したそれぞれのセレクタの詳細度を最も大きいセレクタに統一しちゃう。つまり、すべてのセレクタの詳細度の違いにかかわらず、均一にする。そう、これこそ:is()をセレクタの平均律と呼ぶ所以。
    たとえば、次の例。

    :is(
    #hero .of #world,
    #demonload,
    .villagefolk,
    .soldier,
    span
    )

    この場合、もっとも詳細度が強いのは#hero .of #worldで(2, 1, 0)になる。だけど:is()はすべてのセレクタの詳細度を(もっとも弱い村人のspanですら)ヒーローの(2, 1, 0)に統一するってことなんだ。
    セレクタが10個あったとして、それぞれの詳細度がバラバラであっても、:is()は10個すべての詳細度を一番高い詳細度で均一にしてしまう。これってもう全音階・全等分平均律ってことじゃない。つまり、セレクタの平均律・調律師って言ってもいいんじゃない。
    これは競争のない世界を創るね。:is()もwhereと同じく争いを生まない疑似クラスなんだね。

使い方

平均律セレクタ:is()の使い方は

  • すべてが均一

    :is()はグループ内のセレクタの詳細度を全て同じにするって言ったよね。これの何がいいか?設計が非常に楽になる。すべてが均一なので、『詳細度で負けたからスタイルが効かない!』が発生しない。
    これは、たとえばグループの状態がhoverの時など、非常に使いやすい。

    意味・役割・状態でグルーピングする。

    :is(button, span, div, svg, img, .link, #home):hover{
    filter: brightness(110%) saturate(120%);
    }

    こういった場合、buttonが#homeより詳細度が低いからスタイルが効かないなどは発生しない。なぜならすべてが均一だから。もちろん、これは分かりやすさを説明するためのサンプル。あえて素のHTML要素とIDをグループ化しているけど、実践ではこういうことはしない。

    で、例えば、下記の様なHTMLがあったとして

    <section>
        <a id="home" href="#">anchor-home</a>
        <a href="#">anchor</a>
        <a class="link" href="#">anchor-link</a>
        <div class="divlink">divLink</div>
        <div class="link">link</div>
        <button>button</button>
        <div id="about">div#about</div>
    </section>
  • CSSを

    :is(button, a, span, div, div.divlink, svg, img, .link, #home, #about){
        d:is()play: inline-block;
        margin-bottom: 12px;
        padding: 4px 8px;
        color: rgb(33, 108, 179);
        background: rgb(243, 248, 252);
        border: solid 1px #919090;
        border-radius: 8px;
    }
    
    :is(button, a, span, div, div.divlink, svg, img, .link, #home, #about):hover{
        filter: brightness(110%) saturate(120%);
    }
  • とするとグループ内のどのセレクタにも、均等にマウスオーバー時の挙動を設定できる。
    マウスを乗せるとちょっと全体が明るくなるイメージだ。

    :is()を使ったサンプル:https://labo.studio-happyvalley.com/is/base

注意点

  • 注意点を解説

    さて、ここで注意すべき点を解説する。ちょっと最初のサンプルはセレクタが多すぎるので少なくしたサンプルが下記。

    /* CSS +++++++++++++++++++++++++++++++++ */
    
    :is(a, .outer, #home){
        d:is()play: inline-block;
        margin-bottom: 12px;
        padding: 4px 8px;
        color: rgb(33, 108, 179);
        background: rgb(243, 248, 252);
        border: solid 1px #dad9d9;
        border-radius: 8px;
    }
    
    :is(a, .outer, #home):hover{
        filter: brightness(110%) saturate(120%);
    }
    
    HTML
    <!-- HTML ++++++++++++++++++++++++++++ -->
    
    <section>
        <a href="#">anchor-only</a>
        <a id="home" href="#">anchor-home</a>
        <a class="outer" href="#">anchor-outer</a>
    </section>
    
  • 注意すべきは新たなスタイルの追加

    で、ここで注意すべきは新たにスタイルを追加したい時だ。たとえば、アンカータグにクラス『new』を追加し、文字色と背景色を変更したいとする。

    /*アンカータグにクラスnewを新たに追加*/
    a.new:hover{
        color:rgb(243, 248, 252);
        background: rgb(33, 108, 179);
    }
    
    <section>
        <a href="#">anchor-only</a>
        <a id="home" href="#">anchor-home</a>
        <a class="outer" href="#">anchor-outer</a>
        <h3>アンカータグにクラスnewを新たに追加</h3>
        <a class="new" href="#">anchor-new</a>
    </section>
    
  • ところがこれはスタイルが効かない。なぜなら、最初のグループの詳細度(1,0,0)に新しいセレクタの詳細度(0,2,1)が負けているから。つまり、最初の:is()のグループ化にIDを入れたのがそもそもの間違いということだ。
    :is()の使い方が悪いサンプル|追加前:https://labo.studio-happyvalley.com/is/next
    :is()の使い方が悪いサンプル|追加後:https://labo.studio-happyvalley.com/is/addnew

  • :is()のグルーピングには強い詳細度はまぜない

    強い詳細度をグループ化したいときは:is()ではなく:where()を使うべき。:is()でグルーピング可能なケースでは:where()も使えることがほとんどなので、慣れないうちは:where()だけを使うというのもありだろう。

  • じゃあ、:is()は不要?

    ただし、:where()は詳細度ゼロなので、普通の要素やブラウザの標準スタイルにも負けてしまう。たとえば.hover { background: blue; } みたいな誰かが後で書いた軽いルールにコロッと負けてしまう、爆!!
    あるいは、この色だけは!この状態識別だけは統一したい!そういうケースは非常に多い。そういう時に:is()を使うようにするのが良い。

実は:is()はラッパーでもあった

  • :is()の真価

    たとえば下記。
    :is(
    :where(#main,#container),
    :is(.primary,.secandary,.contents),
    ) a:hover

    内側の :where(...): ここで ID (#main など) の強大な詳細度を 0 にリセット。
    内側の :is(...): ここでクラスの詳細度を統一。(0,1,0)
    外側の :is(...): 中身にある詳細度0のセレクタを統一した詳細度へ引き上げる。(0,1,0)
    結果: 「特定の場所にある a:hover (0,1,1)」という条件をまとめつつ、詳細度を(0,2,1)レベルに統一できる。

    簡単に上書きされないけど、特定のIDなどだと上書きできる!というような魔法が可能になる。
    つまり :is() は平均律の調律師としてだけでなく「ラッパー」(字が違うけど爆!)として超優秀ということだね。

    ※:hoverなどの疑似クラスはクラスの詳細度をもつ。

    :is()の使い方が素敵なサンプル|追加後:https://labo.studio-happyvalley.com/is/comp

:is()の
真価

:is()は:where()との併用や入れ子にすることで真価を発揮する、平均律の調律師・兼ラッパー

  • 可読性の問題はあるけど、他の疑似クラスと併用することで真価を発揮

    ということで最初にもどるけど、:is()を使う場合も、常に『構造と詳細度を分離する』という考えは基本だね。
    また:is()の中にwhereを入れることや、自分自身もネスト可能なので、さきほどのように可読性が悪くならない程度に併用することも一考に値すると思う。私的にはこれが:is()の真価を発揮させる正しい使い方だと思うね。さらに疑似クラスには:has()というラスボスも控えているからね。これを併用するとさらに凄い魔法ができるね。

次回
予告

次回は何

  • レスポンシブの新しい概念を紹介

    次回はCSS革命でも簡単に紹介した、レスポンシブデザインの新しい概念を紹介します。
    レスポンシブ関連の新しいCSSにはアットルールや、プロパティなどいくつかありますので少しづつ紹介したいと思います。
    また、概念も線から面へと移行していいて、特に近年はアスペクト比が重視されています。ということで、まずはいろいろ応用の効く『aspect-ratio』を取り上げます。

この記事の続きは『無限分身の忍術使いAspect-Ratio』でご覧になれます。

『セレクタの平均律系調律師:is()。』関連のお薦め

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