階層を意識したCSSセレクタの指定 / Sass

セレクタは右から左に解釈されるため、セレクタの階層を減らせばレンダリング効率は上がるようです。とはいえ、実際のCSSの管理を考えると必要以上に手間をかけるかどうか悩ましいところなので、できるだけ意識する程度で良い気もします。特にSassでCSSを書く場合、その書きやすさから階層を深く書いてしまいがちです。

検証として機能モジュール別にクラスを管理する方法を5つ挙げてみます。

親のモジュール名を子要素にも付加して孫セレクタを書かない

要素名すべてに共通クラスを付加してCSSでプロパティ指定する方法です。HTML・CSS共にコーディングの手間が増えますが「すべてのアンカーを探す」というようなことは防げます。また、処理コストがかからないように孫セレクタを書かないようにします。この方法が残念なのはSassの良さを活かせてない点です。

jade(pug)

section.m-idx-post
    h3.ttl-idx-post 投稿インデックスのタイトル
    ul.body-idx-post
        li.list-idx-post: a.link-idx-post(href='#') テキストが入ります。

Sass (Indent Syntax)

.m
    @at-root
        &-idx-post
            .ttl-idx-post
                ...
            .body-idx-post
                ...
            .list-idx-post
                ...
            .link-idx-post
                ...

可能な限り機能モジュールを細分化する

1と異なるのはタイトル用要素の指定です。タイトル用クラスの使い回しを良くします。

jade(pug)

section
    h2.m-ttl 投稿インデックスのタイトル
    ul.m-idx-post
        li.list-idx-post: a.link-idx-post(href='#') テキストが入ります。

Sass (Indent Syntax)

.m
    @at-root
        &-ttl
            ...

        &-idx-post
            .list-idx-post
                ...
            .link-idx-post
                ...

可能な場合は機能モジュールを細分化し、バリエーションはマルチクラスで管理する

さらにバラす一方で、記述コストを優先してレンダリング解釈を一部ダブらせます。

jade(pug)

section
    h2.m-ttl.blk 投稿インデックスのタイトル
    ul.m-idx.post
        li.list: a.link(href='#') テキストが入ります。

Sass (Indent Syntax)

.m
    @at-root
        &-ttl
            ...

            &.blk
                ...

        &-idx
            ...

            .list
                ...
            .link
                ...

            &.post
                ...

                &.list
                    ...
                &.link
                    ...

可能な場合は機能モジュールを細分化し、後からの可読性を優先する

バラしたものを一部戻します。最前ではないことは理解しつつも今はこの方法を使ってます。

jade(pug)

section
    h2.m-ttl.blk 投稿インデックスのタイトル
    ul.m-idx-post
        li.list: a.link(href='#') テキストが入ります。

Sass (Indent Syntax)

.m
    @at-root
        &-ttl
            ...

            &.blk
                ...

        &-idx-post
            ...

            .list
                ...
            .link
                ...

        &-idx-other
            ...

            .list
                ...
            .link
                ...

BEMで書く

子孫セレクタを書かず、親・子・孫の管理をしやすくするベストな方法はBEM記法になるはずです。最近まではこの方法を使っていましたが、孫のクラス名が必然的に長くなることと共通クラスの使い回しが悪いこと、HTMLマークアップのコストが高くてやめました。一時はSass記述がラクだったので気に入って使っていたので、この良さを活かせないものか検証中です。

BEMについてはBEMによるフロントエンドの設計 – 基本概念とルール | CodeGridに詳しく書かれています。

jade(pug)

section.idx-post
    h2.idx__post__ttl 投稿インデックスのタイトル
    ul.idx__post__body
        li.idx__post__body__list: a..idx__post__body__link(href='#') テキストが入ります。

Sass (Indent Syntax)

.idx-post
    @at-root
        &__ttl
            ...
        &__body
            ...
            @at-root
                &__list
                    ...
            @at-root
                &__link
                    ...

レンダリングコスト vs 記述コスト

他のことでできることはやりつつも、HTML・CSSの記述に意識を向けてみると改善できることはまだまだあるようです。引き続き検証を続けていきたいと思います。