SassのMixinとExtend/Inheritance

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

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

TODO:前回のエントリー

参考にした書籍

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

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

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

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

mixinを定義する

次にmixinを定義してみたいと思います。mixinとはスタイルの定義部分を共通の定義として、その定義をそれぞれのスタイルで共有するための仕組みです。

変数を切り出した時のように、スタイルの定義部分から共通な部分を切り出します。今回はやや強引な気がしますが、spanタグのbefore擬似属性とhover擬似属性から共通の部分を切り出してmixinしてみます。

...
div.tooltip1{
...
  span {
    &:before{
      ...
      display:block;
      position:absolute;                         /* relativeからの絶対位置 */
      z-index:100;
     ...
    }
  }

  /* マウスオーバー */
  &:hover {
...
    & span{
      display: block;                  /* ボックス要素にする */
      position: absolute;            /* relativeからの絶対位置 */
      z-index:100;
     ...
    }
  }
}

この通り、下記の部分が共通な内容となっています。

display: block; 
position: absolute;
z-index:100;

この部分を以下の通りmixinとして定義します。

@mixin span-position-conf{
display: block; 
position: absolute;
z-index:100;
}

このmixinを利用して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{
  @mixin span-position-conf{
    display: block;
    position: absolute;
    z-index:100;
  }

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

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

    &:before{
      @include span-position-conf;
      content:'';
      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);
    }
  }

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

    & span{
      @include span-position-conf;
      top: 25px;
      font-size: 90%;
      color: $text-font-color;
      background-color: $tooltip-back-ground-color;
      width: 205px;
      padding: 5px;
      border-radius:3px;
    }
  }
}

これでSassファイルの見通しがやや良くなりました。(本当はもっと意味のある内容をmixinするべきなのですが…)

なお、今回mixinを定義した場所はdiv.tooltip1になります。その結果、このspan-position-confを参照可能なスコープはdiv.tooltip1以下となります。. text1などで利用したい場合にはspan-position-confを定義する場所を変更する必要がありますので注意してください。

Extend/Inheritanceについて

Extend/InheritanceではExtend/Inheritance

This is one of the most useful features of Sass.

と説明しています。最も役に立つ機能であればスルーすることはできないでしょう。

Extend/Inheritanceとは、そのものずばり定義しているスタイルを異なるスタイルに取り込むことができる機能です。

具体的には、

.message {
  border: 1px solid #ccc;
  padding: 10px;
  color: #333;
}

.success {
  @extend .message;
  border-color: green;
}

.error {
  @extend .message;
  border-color: red;
}

.warning {
  @extend .message;
  border-color: yellow;
}

のように@extend [拡張するクラスなどの名称]を指定します。この例はとてもわかり易い例でメッセージクラスを定義して、そのメッセージクラスを拡張したsuccess/error/warningクラスを作成しています。

またまたあまり適切ではないですが、使い方の雰囲気だけまとめました。

$text-font-color: #0f0f0f;

.title1{
  color: $text-font-color;
  background-color: cadetblue;
  font-size: 20px;
}

.text1{
  @extend .title1;
  font-size: 16px;
}

...

ここではtitle1クラスに定義している内容を.text1クラスでも適用できるように拡張しました。.text1では@extend .title1.title1の内容を拡張しています。

まとめ

Sassを利用することのメリットは伝わりましたでしょうか。前回の入れ子もそうですが、Sassを利用することでDRYな構造を定義できることが一番のメリットでしょう。ぜひSassを利用してみてください。

ソースコード

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

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

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