[CSS] `:hover`などのネスト時の親要素参照(`&`)有無による挙動の違い

4 min read

概要

SCSS(SASS)やCSS in JSのようなメタ言語を用いてネスティングを行う場合、&を使うことで親要素を参照できる。

そういう状況の中で、&がない場合のコードを見かけたのでどういった動作をするのか、&を付けるべきなのかを確認した。

動作検証

以下のパターンをそれぞれ検証する。

  • &がある
    a {
      &:hover {
        color: red;
      }
    }
    
  • &がない
    a {
      :hover {
        color: red;
      }
    }
    

SCSS(SASS)

&がない場合、記述通りの出力(ビルド)結果となる。

出力結果は以下の通りで、&がないとa :hoverというセレクタが生成されるため、:hoverスタイルが正しく適用されない。

a:hover {
  color: red;
}

a :hover {
  color: red;
}

これだと意図しない挙動になるため、&を付けることが必要である。

デモ

SASSのPlaygroundはこちら


CodePenでの動作は以下。

CSS in JS

CSS in JSであるstyled-componentsEmotionは、内部でstylisというSCSSライクな記法ができるCSSプリプロセッサを搭載している。

stylis に&のない記述を渡した場合の出力結果は以下の通り。SASSと同じく&がないとa :hoverとなっている。

a:hover {
  color: red;
}

a :hover {
  color: red;
}

stylisは&を付けないとa :hoverと出力されるが、styled-componentsやEmotionでは&を付けなくとも自動的に正しいa:hoverとして出力される場合がある。

CSS nesting

SCSS(SASS)ライクにネスト記法ができるCSSのネイティブな「CSS nesting」は、現在モダンブラウザでは利用可能となっている。

CSS nestingを利用してみる。以下のような記述でシンタックス的には問題はない。

a {
  &:hover {
    color: red;
  }
}

a {
  :hover {
    color: red;
  }
}

結果として、&がない場合は有効なCSSとして評価されずマウスオーバー(:hover)時のスタイルが適用されない。

まとめ

一部のライブラリが補完をしてくれるからと言って、そもそもの記述方法として&を使わないとa :hoverとなってしまうのは当然の結果であり、&を使うことが正しい記述方法である。

親子関係を正確に表現し、意図したスタイルを確実に適用するためにも、常に&を付けて記述することを推奨する。特にSCSSやCSS in JS環境でのセレクタ生成時には、&を省略せずに用いることで、予期せぬスタイル適用ミスを防ぐことができる。