#2 「SCSS入門講座」 ネストや親セレクタの参照など基本的な拡張機能について学ぼう

今回はSCSSを使うなら 最低限 知っておいて欲しい便利な機能について学んでいきましょう。これさえできればかなりCSSを書くスピードも速くなります。

セレクターのネスト

SCSSでは、セレクターを ネスト することができます。これによって、要素の親子関係 がより分かりやすくなります。


<main class="main">
  <h1>見出し</h1>
  <p>文章</p>
  <p class="warning">警告</p>
  <p>文章<b>太字</b></p>
</main>

.main {
  color: #555;
}
.main h1 {
  font-size: 2em;
}
.main p {
  font-size: 1.1em;
}
.main p.warning {
  color: red;
}
.main p b {
  font-weight: bold;
}

例えば、上記HTMLに対して、いつも通りCSSでスタイルを定義していくとこんな感じになります。何度も .main.main p が記述されており少し冗長ですよね。これはまだ非常にシンプルなHTMLの構造なので気にならないかもしれませんが、より大規模で複雑 になってくるとCSSとして見づらいものになってきます。


.main {
  color: #555;
  h1 {
    font-size: 2em;
  }
  p {
    font-size: 1.1em;
    b {
      font-weight: bold;
    }
  }
  p.warning {
    color: red;
  }
}

そこで、SCSSを使うとこのように HTMLの階層関係 と同じようにネストして記述することができます。普通にCSSを書くより記述量も短いし、見やすくなったと思います。

複数の要素に対してネスト


.main p, .main div {
  color: #555;
}

.main 要素内の pdiv 両方に同じスタイルを定義したい場合も考えてみます。


.main {
  p, div {
    color: #555;
  }
}

SCSSでもCSSと同じように カンマ で区切ることで表すことができます。

子孫セレクタ以外も


.main {
  > p {
    font-size: 1.1em;
    + p {
      margin-top: 1em;
    }
  }
}

.main > p {
  font-size: 1.1em;
}
.main > p + p {
  margin-top: 1em;
}

CSSと同じように 子セレクタ>)や 隣接セレクタ+)を使うことができます。

@mediaのネスト


.main {
  h1 {
    font-size: 1.5em;
    @media screen and (max-width: 414px) {
      font-size: 1.2em;
    }
  }
}

.main h1 {
  font-size: 1.5em;
}
@media screen and (max-width: 414px) {
  .main h1 {
    font-size: 1.2em;
  }
}

レスポンシブデザインを作る際に必須の CSSメディアクエリ もネストして記述することができます。コンパイル後のCSSのようにメディアクエリを分けて書く必要がないので、非常に見やすくなります。

親セレクタの参照


a:hover {
  color: #000;
}

ホバー時のスタイルを定義したいときはどうすればいいでしょうか。


a {
  :hover {
    color: #000;
  }
}

ネスト の知識を使ってこんな風に書けるかなと思うかもしれません。


a :hover {
  color: #000;
}

しかし、結果はこのように間に スペース が入ってしまって意図したものとは異なります。これはネストを理解していれば当然の挙動であると分かるはずです。ネストで記述されたものは階層として認識されるので、a というセレクタの中に :hover というセレクタがあるという関係から、a :hover と出力されるのです。


a {
  &:hover {
    color: #000;
  }
}

意図したように出力したい場合は、このように :hover の直前に & を追加します。& には 親セレクタを参照 する機能があります。ここでの 親セレクタa になるので、&a に置換されます。

&が何を指しているか具体例で見てみる


.main {
  &:hover {  /* & = .main */
    color: red;
  }
  p {
    &:hover {  /* & = .main p */
      color: blue;
    }
    > b {
      &:hover {  /* & = .main p > b */
        color: green;
      }
    }
  }
}

.main:hover {
  color: red;
}
.main p:hover {
  color: blue;
}
.main p > b:hover {
  color: green;
}

SCSSとコンパイル後のCSSを見比べてみると、& がそれぞれ置き換わっているのが分かると思います。&その階層より上に記述された全部のセレクタ を表す変数のようなものです。

&を使って効率よくCSSを定義


.button {
  display: inline-block;
  padding: .7em 1.5em;
  color: #333;
  border: 1px solid #333;
  &.big {  /* & = .button */
    font-size: 1.2em;
  }
  &.small {  /* & = .button */
    font-size: .8em;
  }
}

.button {
  display: inline-block;
  padding: .7em 1.5em;
  color: #333;
  border: 1px solid #333;
}
.button.big {
  font-size: 1.2em;
}
.button.small {
  font-size: .8em;
}

& を活用すると簡単に マルチクラス に対応させることができます。& 自体が何を指しているのか理解することができれば使いこなすことができるようになると思います。

親要素のクラス名の一部を利用


.button {
  display: inline-block;
  padding: .7em 1.5em;
  color: #333;
  border: 1px solid #333;
  &-big {
    font-size: 1.2em;
  }
}

.button {
  display: inline-block;
  padding: .7em 1.5em;
  color: #333;
  border: 1px solid #333;
}
.button-big {
  font-size: 1.2em;
}

先ほどはマルチクラスにしましたが、単純にハイフンつなぎで 親要素のクラス名を継承 したい場合はこのように書くことができます。

親要素によってCSSを変えたい


.button {
  display: inline-block;
  padding: .7em 1.5em;
  color: #333;
  border: 1px solid #333;
  .is-top-page & {
    display: none;
  }
}

.button {
  display: inline-block;
  padding: .7em 1.5em;
  color: #333;
  border: 1px solid #333;
}
.is-top-page .button {
  display: none;
}

例えば、このようなSCSSを書けば、トップページのみボタンを非表示 にする処理を分かりやすく書くことができます。このときの & は親要素である .button を指しているのでコンパイル結果も理解できると思います。

プロパティのネスト


.selector {
  border-left-width: 1px;
  border-left-style: solid;
  border-left-color: #000;
}

例えば、このようなCSSがあったときSCSSでは次のように書くことができます。


.selector {
  border: {
    left: {
      width: 1px;
      style: solid;
      color: #000;
    }
  }
}

ハイフン で区切って ネスト にしているイメージです。しかし、僕自身この機能は全く使いません。


.selector {
  border: 1px solid #000;
}

なぜかというと、大抵CSSには ショートハンド と呼ばれる複数のプロパティをまとめて記述できる方法があり、わざわざプロパティのネストを使うことはないからです。SCSSではこんなこともできるよ程度に思っておいてください。