CSS @layer カスケードレイヤーの罠

web言語ロゴ

本日はCSSの新しめの機能 @layer カスケードレイヤー の罠に関して話して行きたいと思います。

カスケードレイヤーについての細かい説明は他に詳しく説明してくださっているサイトさまがいくつかありますので、そちらで学んでいただけたらと思います。

ここでは簡単にさわりと注意点だけ紹介させていただきます。

1.@layerとは

記述したCSS優先順位を指定するモノという認識でとりあえずよいと思います。
学習しようとする多くの人は!importantを回避するために使ってみようかな?と調べてみる人が多いかもしれません。

ではまず、CSSの優先順位に関しておさらいをします。
※もっと詳細な決まりや順番がありますが簡単に話します。

  1. !importantで指定したモノ
  2. インラインに直接記述したモノ
  3. idセレクタ(#)で指定したモノ
  4. classセレクタ(.)で指定したモノ

1が1番優先順位が高く、4に向けて低くなっていきます。
そのほかに読み込む順番、詳細度(※1)によって変わったりもしますが、普段特に意識して指定する形は上記の内容だと思います。
(※1) .text{font-size:40px;}より、.page .text{font-size:20px;} の方が優先される。

そして今回の主役である@layerを利用した命令はどの位置に来るかと言いますと、上記リストで言う場合2と3の間に入ることになります。

そもそもcssの指定はid名ではなく、class名で指定することがほとんどだとは思いますが、idで指定したモノより優先されるということは!importantを使わなければ外部シートの読み込みの中では1番優先度が高くなると言ってもよいのでしょう。

2.@layerの使い方

@layer name;

@layer name {
  .text {
    font-size:20px;
  }
}

@charset “utf-8”;のように、@layer 任意の名前 でまずレイヤー名を宣言します。

特定のセレクタに宣言したレイヤーを利用する場合は、メディアクエリ(@medeia)を利用する時と同じように対象のセレクタを括弧で囲います。

レイヤーは複数宣言することが出来ます。
複数利用する場合は、下記のように,(カンマ)で区切ります。

@layer name, reset;

@layer name {
  .text {
    font-size:20px;
  }
}

@layer reset {
  body {
    margin:0;
  }
}

複数宣言した名前は後ろの方にあるモノが優先されます。

3.@layerの罠

では今回のテーマである@layerの罠に関して記述していきたいと思います。

冒頭で触れましたが@layerを利用しようとする人の中には!importantからの脱却を目的に取り入れようとする人が割と多いと思います。

その場合、例えば下記のような罠にハマってしまう可能性があります。
※良い例が浮かばなかったので構造に無理やり感あります。

CSSの読み込み順的には.txtの方が下に来ていますが、.example .txtの方が詳細度が高いので、colorはblueが適用されています。

この状態でcolorにredを適用させたい場合は、color: red!important;とすることで簡単に解決出来ますが、!importantは脱却したいので@layerを使ってみたいと思います。

はい。これが罠です。
これでテキストカラーはredになると思いましたがblueのままです。

1.@layerとはの部分で優先順位について話しましたが、layer名で囲えば!importantを付けるのと同じように単純に優先度が上がると思っていました。

ただ、そうではなくレイヤー(@layer)を使う場合、レイヤーの外に記述されたモノは無名レイヤーと呼ばれる形で宣言されているとみなされ、無名レイヤーは名前の付いているレイヤーより優先度が高くなるようです。

つまりこの場合、囲わなければいけないのは.txtではなく、.example .txtの方だった訳です。

上記例だと感覚的には.example .txtの優先度を下げているという形ですね。

ですので、もしimportant的に使いたい部分とそうでないモノを2つに分けるとしたら、important的に使いたい部分以外のCSSを全て、宣言したレイヤーで囲わなければならないということです。

そのように考えると、気軽に置き換えられるモノではなく、@layer カスケードレイヤーを使う場合は、ある程度しっかりとしたCSS設計が求められることになると思いますし、なんとなくですが@layerを使うよりは命名規則などをしっかりしてclass名で階層をしっかり作っていった方がメリットが大きい気もしています。

 

Categories: CSS