Sassで入れ子による構造化を行う

こんにちは。beaglesoftの真鍋です。

今回はSassで入れ子セレクタと親セレクタの指定について試してみました。CSSでは同じものを構造化することができないことが不便に感じられます。DRYに定義できないためですね。Sassではスタイルを構造化した記述ができるので、ファイルがすっきりします。

TODO:前回を表示

参考にした書籍

今回はフロントエンドエンジニアのための現在とこれからの必須知識を参考にしました。この書籍でネット上に散らばっているフロントエンドに関する知識がまとまっているのでぜひ目を通してみてください。

フロントエンドエンジニアのための現在とこれからの必須知識

フロントエンドエンジニアのための現在とこれからの必須知識

  • 作者: 斉藤祐也,水野隼登,谷拓樹,菅原のびすけ,林優一,古沢宏太
  • 出版社/メーカー: マイナビ出版
  • 発売日: 2016/01/28
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログ (1件) を見る

入れ子と親セレクタ

Sassファイルを見ているとdiv.toolbar1 ...という記述が目立ちします。このようにdiv.toolbar1を親とするスタイルの定義は階層化することができます。

$text-font-color: #0f0f0f;

.tittle1{
  color: $text-font-color;
  font-size: 20px;
}

.text1{
  color: $text-font-color;
  font-size: 16px;
}

/* 以下のURLを参考にしました。 */
/* CSSで作るツールチップ | Web’Notes http://webnonotes.com/css/tooltip/ */
$tooltip-back-ground-color: #5BB2C1;

div.tooltip1{
  color: $text-font-color;
  display: inline-block;                        /* インライン要素化 */
  border-bottom:dashed 1px $text-font-color;    /* 下線を引く */

  /* ツールチップ部分を隠す */
  span {
    display: none;
  }

  /* マウスオーバー */
  :hover {
    position: relative;
    color: #333;
  }

  /* マウスオーバー時にツールチップを表示 */
  :hover span {
    display: block;                  /* ボックス要素にする */
    position: absolute;            /* relativeからの絶対位置 */
    top: 25px;
    font-size: 90%;
    color: $text-font-color;
    background-color: $tooltip-back-ground-color;
    width: 205px;
    padding: 5px;
    border-radius:3px;
    z-index:100;
  }

  /* フキダシ部分を作成 */
  span:before{
    content:'';
    display:block;
    position:absolute;                         /* relativeからの絶対位置 */
    height:0;
    width:0;
    top:-13px;
    left:15px;
    border:13px transparent solid;
    border-right-width:0;
    border-left-color:$tooltip-back-ground-color;
    transform:rotate(270deg);            /* 傾きをつける */
    -webkit-transform:rotate(270deg);
    -o-transform:rotate(270deg);
    z-index:100;
  }
}

ここでもう少し修正したSassファイルを確認してみます。まだ重複している箇所がいくつかあります。

...
div.tooltip1{
...
  span {
    ...
  }

  :hover {
    ...
  }

  :hover span {
    ...
  }

  span:before{
    ...
  }
}

この通りspan:hoverは重複しているためさらにまとめられそうです。ただ、今回はすでに入れ異なる定義を行っているため少し工夫が必要になります。

...
div.tooltip1{
...
div.tooltip1{
...
  span {
    ...
    &:before{
      ...
    }
  }

  /* マウスオーバー */
  :hover {
    ...
    & span{
      ...
    }
  }
}

先ほど重複があった部分について、さらにまとめました。まとめるときには入れ子になっているスタイルではわかりやすく親の属性として&を利用しています。

具体的には下記のaの部分が該当します。

 span {
    ...
    &:before{   /* ←a.この& */
      ...
    }
  }

これは、変更前はこのようになっていました。

  span {   /* 1 */
    ...
  }

  span:before{ /* 2 */
    ...
  }

1と2はそれぞれspanタグを親として持ちますが、2はbefore擬似要素が設定されています。このとき、2についてはspanが親であることを明示するため&を設定しています。

つけない場合でもspanタグを親としたCSSが生成されていましたがわかりやすさから考えるとつけたほうが良いように思います。

最終的には以下の様なSassファイルとなります。

$text-font-color: #0f0f0f;

.tittle1{
  color: $text-font-color;
  font-size: 20px;
}

.text1{
  color: $text-font-color;
  font-size: 16px;
}

/* 以下のURLを参考にしました。 */
/* CSSで作るツールチップ | Web’Notes http://webnonotes.com/css/tooltip/ */
$tooltip-back-ground-color: #5BB2C1;

div.tooltip1{

  color: $text-font-color;
  display: inline-block;                        /* インライン要素化 */
  border-bottom:dashed 1px $text-font-color;    /* 下線を引く */

  /* ツールチップ部分を隠す */
  span {
    display: none;

    &:before{
      content:'';
      display:block;
      position:absolute;                         /* relativeからの絶対位置 */
      height:0;
      width:0;
      top:-13px;
      left:15px;
      border:13px transparent solid;
      border-right-width:0;
      border-left-color:$tooltip-back-ground-color;
      transform:rotate(270deg);            /* 傾きをつける */
      -webkit-transform:rotate(270deg);
      -o-transform:rotate(270deg);
      z-index:100;
    }
  }

  /* マウスオーバー */
  &:hover {
    position: relative;
    color: #333;

    & span{
      display: block;                  /* ボックス要素にする */
      position: absolute;            /* relativeからの絶対位置 */
      top: 25px;
      font-size: 90%;
      color: $text-font-color;
      background-color: $tooltip-back-ground-color;
      width: 205px;
      padding: 5px;
      border-radius:3px;
      z-index:100;
    }
  }
}

まとめ

ちょっと長くなりましたが、Sassの入れ子はとても便利なのでぜひ利用してみてください。

ソースコード

今回のソースコードは以下のリポジトリにあります。参考にしてください。

https://github.com/yoichiro-manabe/gulp_example2

※リポジトリがgulp_example2となっているのですが、READMEにあるとおりgulpについて試していたリポジトリをそのまま利用したためです。綺麗にリポジトリを管理できていないのですが、そこは「ノリと勢いだけ」で頑張ったということでご容赦を。