LIGのメルマガ、はじめました!
LIGのメルマガ、はじめました!

&__foo 記法は、SassとCSS(W3C草案)とで意味が変わる

つっちー

こんにちは。エンジニアのつっちーです。

&__foo

みなさんはSassでこのような記法を目にしたことはあるでしょうか。あるいは使用されているでしょうか。主に、設計にBEMを採用している場合によく使われている印象があります。

この記法について、LIGでは賛否両論あります。文字量が減り、記述が簡潔になることがメリットですが、CSSの定義箇所を検索したい場合に、HTML上のクラス名をそのまま検索文字列として利用できなくなるデメリットもあるためです。

社外でもかなり多く見かける記法のため、利用すべきかどうか長らく迷ってきました。今回は、その判断材料となりうる情報を新たに発見したため、備忘録の意味も込めて記事に残したい思います。

それが、タイトルにもある「SassとCSS(W3C草案)とで意味が異なる」というものです。

この記事で参照している草案はこちらです。
CSS Nesting Module

どのように違うのか

以下の記述について、Sass(SCSS)としてCSSへ変換した結果と、W3C草案に沿ったCSSとしての解釈とを比較してみます。

.foo {
    color: black;

    &__bar {
        color: red;
    }

    &__baz {
        color: green;
    }
}

Sass(SCSS)としてCSSへ変換した結果

__bar, __baz が .foo と合わさり、それぞれ一つのクラスとなっています。

.foo {
    color: black;
}

.foo__bar {
    color: red;
}

.foo__baz {
    color: green;
}

W3C草案に沿ったCSSとしての解釈

W3C草案に沿うと、以下のCSSと同等のものとして解釈されます。__bar, __baz は要素名という解釈になり、.foo はそのうしろに移動しています。

.foo {
    color: black;
}

__bar.foo {
    color: red;
}

__baz.foo {
    color: green;
}

一見おかしな解釈に感じられますが、これはカスタム要素の仕様が考慮された挙動のようです。

__bar, for example, is a valid custom element name in HTML.

divやspanと同様に、__bar, __baz も(カスタム)要素の名前かもしれないため、ということでしょうか。ただ、customElements.define() を使ってカスタム要素を作成する場合、アンダースコアで始まる名前ではエラーとなるため、実際には __bar, __baz といったカスタム要素が作られることはないような気もします。

さてどうしよう

私は、なるべく標準に寄せていきたい考えから、BEM目的では &__foo 記法を使わないことにしました。ただ、この草案は最も早い段階のFirst Public Working Draftであり(2021年9月時点)、勧告となるまでに仕様変更される可能性が大いにあります。

SassとCSS(W3C草案)の間に差があるというだけで、この記法を推奨しないという意図もありません。他の事情とも合わせ、判断材料の一つにしてもらえれば幸いです。

ではまた! つっちーでした。