🗂

詳細度 からカスケードレイヤー

2023/08/25に公開

詳細度とは

ある要素のCSSを決定するためのアルゴリズム。

詳細度の強さ

!important

1-0-0-0-0

インラインスタイル

0-1-0-0-0

ID

0-0-1-0-0

クラス

0-0-0-1-0

要素型

0-0-0-0-1

<div id="block" class="block">
  <p id="content" class="content">test</p>
</div>
#block {
  color: red;
}
.content.content {
  color: lightblue;
}
[id="content"].content {
  color: blue;
}
div > p.content {
  color: coral;
}

この場合は blue になる。

詳細度はここで計算できます。Specificity Calculator

ちなみに styled-component でもスタイルが衝突して優先順位を上げたい際に &&(.class.class) は紹介されてます。
styled-components: Basics

詳細度のまとめ

https://specifishity.com/specifishity.png

カスケードレイヤーとは

CSSカスケードレイヤーは、CSSの厄介な問題を解決することを目的としている。
最近だとIEが消えたので全ブラウザーでサポートされるようになった。

カスケードレイヤーが解決したい厄介な問題

固有値の衝突

セレクタが競合するため、サードパーティーなどのスタイルをオーバーライドしたい状況など。
以下のような方法で競合を避けるようにしてきた。

方法論

  • BEM

    <section>
    	<div class="article">
    		<h1 class="article__header"></h1>
    		<img class="article_image" src="..."/>
    		<button class="article__button--disabled" type="button">Link</button>
    	</div>
    </section>
    
  • OOCSS

    <section>
    	<div class="article">
    		<h1 class="header header-bold"></h1>
    		<img class="image image-w128" src="..."/>
    		<button class="button button-disabled" type="button">Link</button>
    	</div>
    </section>
    
  • SMACSS

    <section class="l-content">
    	<div class="article">
    		<h1 class="article-header"></h1>
    		<img class="article-image" src="..."/>
    		<button class="button is-disabled" type="button">Link</button>
    	</div>
    </section>
    
  • FLOCSS

    <section>
    	<div class="c-article">
    		<h1 class="c-article-header"></h1>
    		<img class="c-article-image u-w128" src="..."/>
    		<button class="c-button u-disabled" type="button">Link</button>
    	</div>
    </section>
    
  • ライブラリの使用

    • CSS Modules
    • Styled Components
    • tailwindcss

などカスケードを回避するためにいろいろなベストプラクティスが考えられてきた。

セレクタの順序

https://css-tricks.com/wp-content/uploads/2022/02/layers-tall-outlines2.svg

実際にはカスケードレイヤーはIDセレクターより強く、style属性より弱い優先度となっている。

一番優先されるスタイルは Origin (ブラウザ)

一番優先されるのは ブラウザの style 。これに対して!importantを使っても一部書き換えることはできなくなっている要素が存在する。iframe:fullscreen など。また、カスケードレイヤーにも同じスタイルが適応される。他にもShadow Context を使えば Host の style を!imporant で優先順位を逆転することもできる。

レイヤーの重なり順

@layer layer-1 { a { color: red; } }
@layer layer-2 { a { color: orange; } }
@layer layer-3 { a { color: yellow; } }
a { color: green; }

とあったら、 unlayered style が一番優先されるため、次にlayer-3,layer-2,layer-1と続く。

ここでは agreen になる。

@layer layer-1 { a { color: red !important; } }
@layer layer-1 { a { color: blue !important; } }
@layer layer-2 { a { color: orange !important; } }
@layer layer-3 { a { color: yellow !important; } }
a { color: green !important; }

ただ、 important layer が存在する場合、important が出現した順に優先される。

この場合はlayer-1redblue。また同名のレイヤーがある場合は後のレイヤーが優先されるため、 ablue になる。

レイヤーの構文

  • レイヤー定義

    @layer custom-layer;
    
  • 同じ名前のレイヤーにどこからでもスタイルを追加できる

    @layer custom-layer;
    
    @layer custom-layer { a { color: red; } }
    
  • 自身でレイヤーの順序リストを定義することもできる

    @layer lower-layer, upper-layer;
    
  • グループ化してスタイルも追加できる

    @layer parent {
      @layer child1, child2;
    	@layer child1 {
        a: { color: red; }
      }
      @layer child2 {
        a: { color: blue }
      }
    }
    @layer parent.child2, parent.child1;
    @layer paren.child2 {
      a: { color: black }
    }
    
  • 外部からレイヤーを読み込むこともできる

    @import url('example.css') layer(custom-layer);
    @layer custom-layer { ... }
    
  • レイヤー階層を戻す(ロールバック)

    
    @layer first-layer, second-layer;
    
    @layer first-layer {
      a: { color: black }
    }
    
    @layer second-layer {
    	a: { color: red }
      a:active {
        color: revert-layer;
      }
    }
    

まだドラフトで話し合ってる段階だけど

<link rel="stylesheet" href="remedy.css" layer="reset">

<style layer="reset">
  audio[controls] { display: block; }
</style>

みたいにlayerを指定してcssを読み込める時代が来るかもしれない... 🤔

参考

https://developer.mozilla.org/ja/docs/Web/CSS/Specificity
https://css-tricks.com/css-cascade-layers/
https://developer.mozilla.org/en-US/docs/Web/CSS/@layer
https://github.com/w3c/csswg-drafts/issues/5853

Discussion