Sassの@extendとプレースホルダーセレクタ【CSS Preprocessor Advent Calendar 2012 Day 22】

このエントリーは、 CSS Preprocessor Advent Calendar 2012の22日目の記事です。

この回では、Sassの@extendとプレースホルダーセレクタについて簡単に書きます。

@mixinと@extend

Sassの機能でミックスインとエクステンドがありますが、 これらの使いようがどうなのよと思うところがあるのではないでしょうか。

ミックスイン

@mixin box-class(){
	border: 1px solid #dddddd;
	padding: 5px;
	margin: 0;	
}

.mixinClass1 {
	@include box-class();
}

.mixinClass2 {
	@include box-class();
}

エクステンド

.extendClass1 {
	border: 1px solid #dddddd;
	padding: 5px;
	margin: 0;
}

.extendClass2 {
	@extend .extendClass1;
}

スタイルセットを定義して、それを指定する、という形ですので、 使いようは、同じように見えますが、これらの違いは、コンパイルされるCSSが違います。

ミックスイン(コンパイル後)

.mixinClass1 {
	border: 1px solid #dddddd;
	padding: 5px;
	margin: 0;
}

.mixinClass2 {
	border: 1px solid #dddddd;
	padding: 5px;
	margin: 0;
}

エクステンド(コンパイル後)

.extendClass1, .extendClass2 {
	border: 1px solid #dddddd;
	padding: 5px;
 	margin: 0;
}

御覧のようにエクステンドの場合は、セレクターがグループ化されます。 セレクター数制限がある某ブラウザ向けにコード量を抑えなければならない場合に有効だったりします。

しかし、エクステンドで注意しなければならない指定したセレクタを含むすべてのスタイルが継承されることです。

例(.scss)

例として極端すぎるのですが、以下のような記述があるとします。

.extendClass3 {
	border: 1px solid #dddddd;
	padding: 10px;
	margin: 5px;
	width: 100%;
}

.extendClass4 {
	@extend .extendClass3;
	p {
		font-size: 14px;
	}
}

.wrap {
 .extendClass3 {
	p {
		color: black;
		font-size: 16px;
	}
  }
}

例(.css)

コンパイルされると以下のようなCSSになります。

.extendClass3, .extendClass4 {
	border: 1px solid #dddddd;
	padding: 10px;
	margin: 5px;
	width: 100%;
}

.extendClass4 p {
	font-size: 14px;
}

.wrap .extendClass3 p, .wrap .extendClass4 p {
	color: black;
	font-size: 16px;
}

.wrap .extendClass4 pのように予期していないとした場合に、 余計なセレクタができてしまいスタイルを上書きしてしまう可能性があり、意図したスタイルが当たらないことが起こりうります。

こういった問題を解決してくれる(してくれるかもしれない)のがプレースホルダーセレクタです。

プレースホルダーセレクタ(Placeholder Selectors)

プレースホルダーセレクタは、Sass3.2から使えるようになった再利用できるスタイルセットを%キーワードで指定するエクステンド専用のセレクタです。

%extend-rule {
	property: value;
}

.className {
	@extend %extend-rule;
}

実際に、プレースホルダーセレクタを用いて上記のコードを書き換えると以下のようになります。

例(.scss)

%extend-rule {
	border: 1px solid #dddddd;
	padding: 10px;
	margin: 5px;
	width: 100%;
}

.extendClass3{
	@extend %extend-rule;
}

.extendClass4 {
	@extend %extend-rule;
	p {
		font-size: 14px;
	}
}

.wrap {
 .extendClass3 {
	p {
		color: black;
		font-size: 16px;
	}
  }
}

例(.css)

コンパイル後のCSSは以下のようになります。

.extendClass3, .extendClass4 {
	border: 1px solid #dddddd;
	padding: 10px;
	margin: 5px;
	width: 100%;
}

.extendClass4 p {
	font-size: 14px;
}

.wrap .extendClass3 p {
	color: black;
	font-size: 16px;
}

先ほどと違うのは、「.wrap .extendClass4 p」のセレクタができていません。

このようにプレースホルダーセレクタを使うことで、意図していない、または無駄なセレクタを出力せずにできるようになります。

以上がSassの@extendとプレースホルダーセレクタについてざっくりとした解説でした。まとめると設計次第です(謎)。

例が極端すぎて例じたいは微妙だったかもしれませんが、プレースホルダーセレクタがどういったものかお分かりいただけましたでしょうか。 プレースホルダーセレクタについては、後の方がもっといい感じに書いてくれると思いますので、 引き続き、CSS Preprocessor Advent Calendar 2012をお楽しみください。