Sassの勉強 #02 Sassの基本的な機能「ネスト」
ルールのネスト
Sassではルールをネストを利用して書く事が出来ます。CSSをHTMLの構造に合わせてネストさせて(入れ子にして)書いていく事が出来るので把握しやすく、重複したセレクタを書かんでも良くなるというもの。例えばこんなHTMLがあったとする。
<div id="sample">
<section>
<h1>見出し</h1>
<p>段落</p>
<p class="note">段落</p>
<ul>
<li>リスト</li>
<li>リスト</li>
<li>リスト</li>
</ul>
</section>
<!--/#sample--></div>
上記ソースにCSSを当てようと思うと普通のCSSなら、こんな感じに書く事がある。
/* サンプルCSS */
#sample{
width:90%;
margin:0 auto;
}
#sample section{
color:#000;
}
#sample section p{
font-size:1.5em;
}
#sample section p.note{
color:#f00;
}
#sample section ul{
margin:20px auto;
}
#sample section ul li{
border-bottom:1px solid #999;
padding:0 0 5px;
margin:0 auto 5px;
}
内容は適当なのでアレなんですが、要はセレクタ部分が重複している点を見てほしいのです。Sassのネストを使えば、重複して長くなったセレクタ部分を書く必要がなくなります。また、HTMLの階層状態に沿って書いていくので把握もしやすい、と。Sassのネストを利用して、上のCSSソースを書いてみると、こんな感じになる。
/* ネストを利用したSassのソース */
#sample{
width:90%;
margin:0 auto;
// 以下、入れ子になっております。
section{
color:#000;
p{
font-size:1.5em;
}
p.note{
color:#f00;
}
ul{
margin:20px auto;
li{
border-bottom:1px solid #999;
padding:0 0 5px;
margin:0 auto 5px;
}
}
}
}
HTMLの構造に合わせてCSSも入れ子にして書くことが出来ます。
これをコンパイルするとこうなります。
/* コンパイル後のCSS */
#sample {
width: 90%;
margin: 0 auto;
}
#sample section {
color: #000;
}
#sample section p {
font-size: 1.5em;
}
#sample section p.note {
color: #f00;
}
#sample section ul {
margin: 20px auto;
}
#sample section ul li {
border-bottom: 1px solid #999;
padding: 0 0 5px;
margin: 0 auto 5px;
}
元の普通に書いたCSSのソースと同じになっているのが分かります。
セレクタ「#sample」の中にその「#sample」に関するルールがまとまって書かれているので、後から見直した時に把握しやすいし、ルールを追加する際も便利ですね。ソースの量も減ります。
また、一番良いなと思ったのは、上のサンプルのHTMLでいうところの「section」要素が変更になった際に、scssファイル内のそのsectionというセレクタを1つ書き換えるだけでsectionセレクタが含まれている他のルール全てに反映される点です。全てを書き換える必要がなくなると、書き換え忘れや置換ミスも減ると思いました。
子孫セレクタ以外のセレクタを使う
上の例では「#sample section・・・」のように子孫セレクタについての書き方でしたが、それ以外のセレクタ、例えば子セレクタや隣接セレクタの場合は、入れ子になってるセレクタの前に「+」「>」を入れると良いそうです。
/* 子セレクタ */
#sample{
section{
+ section{
margin:20px auto 0;
}
}
}
/* 隣接セレクタ */
#sample{
section{
> h1{
font-size:1.8em;
}
}
}
上記をコンパイル後はこうなります。
/* 子セレクタ */
#sample section + section {
margin: 20px auto 0;
}
/* 隣接セレクタ */
#sample section > h1 {
font-size: 1.8em;
}
分かりやすいように子セレクタと隣接セレクタを分けて書きましたが、もちろん合わせてsectionの中にいれてOK。下記の用に書いても結果は同じです。
#sample{
section{
+ section{
margin:20px auto 0;
}
> h1{
font-size:1.8em;
}
}
}
@mediaを使う
メディアクエリを使用する際にも、わざわざ離して書かなくてももネストを利用して分かりやすく書くことが出来ます。メディアクエリを使用したいセレクタの中に入れ子で@mediaと内容を指定。
#sample{
float:left;
@media screen and (max-device-width:480px){
float:none;
}
}
/* コンパイル後 */
#sample {
float: left;
}
@media screen and (max-device-width: 480px) {
#sample {
float: none;
親セレクタを参照する「&」
親セレクタを参照する場合は「&」を使用します。
例えばa要素のhover時の挙動を指定したい時。
a{
text-decoration:none;
&:hover{
text-decoration:underline;
}
}
↑こう書くと、こうなる↓
a {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
上の例だとありがたみがあまりわからないかもしれないけれども、教科書に載ってたこんな時にとても良いと思う。
/* #testの幅を指定したいけど、body#indexの中の#testの時だけ違う幅にしたい */
#test{
width:100%;
body#index &{
width:50%;
}
}
/* コンパイル後 */
#test {
width: 100%;
}
body#index #test {
width: 50%;
}
/* .prevと.nextでfloatの値だけ変えたい */
ul.pageNav{
li{
width:50%;
margin:0 auto 5px;
&.prev{
float:left;
}
&.next{
float:right;
}
}
}
/* コンパイル後 */
ul.pageNav li {
width: 50%;
margin: 0 auto 5px;
}
ul.pageNav li.prev {
float: left;
}
ul.pageNav li.next {
float: right;
}
「&」を利用する事でソースの可読性がアップする、と。
プロパティのネスト
Sassのネスト機能はルールセットだけでなく、一部のプロパティでもネスト化したソースを書くことが出来る。プロパティのネストが使えるのは「-(ハイフン)」があるプロパティのみ。
text-なんからーとか、border-なんたらーとか。
今のところ、このプロパティのネストについてはあまり利点がわからないのでアレなんですが、書き方だけ書いておきます。
/* borderに適応 上下で違うborderに。 */
#sample{
p{
border:{
top:2px solid #ddd;
bottom:{
width:3px;
style:dashed;
}
}
}
}
/* コンパイル後 */
#sample p {
border-top: 2px solid #ddd;
border-bottom-width: 3px;
border-bottom-style: dashed;
}
/* borderに適応 bottomの値だけを変更 */
#sample{
p{
border:1px solid #ddd{
bottom:none;
}
}
}
/* コンパイル後 */
#sample p {
border: 1px solid #ddd;
border-bottom: none;
}
このプロパティのネストはその時になったら絶対忘れてそう…な予感。
プレースホルダーセレクタ「%」
Sassにはプレースホルダーセレクタという特別なタイプのセレクタが用意されています。スタイルの継承ができる@extendという機能を使用する時にだけ使うことができるセレクタで、コンパイル後にはソースが残らない。
書き方は class とか id セレクタと同じように書くのだけれども、プレースホルダーセレクタは「#」や「.」の代わりに「%」を使う。
プレースホルダーセレクタを使ってscssファイルにルールを書いておいて@extendで使いまわしして、最終的には無駄なソースは残さずにcssファイルが仕上がる、という仕組み。
/* %fooにルールを記載し、好きなセレクタのとこで@extendで呼び出す */
%foo{
text-align:center;
width:100px;
}
#test{
@extend %foo;
}
/* コンパイル後、%fooは残らない */
#test {
text-align: center;
width: 100px;
}
Sassのコメント
上の方に書いた「ネストを利用したSassのソース 」のサンプルソース内に「// 以下、入れ子になっております。」というコメントが入っていますが、Sassではコメントに「/* */」を利用したコメントの他に「//」を利用したコメントが使用できます。両者の違いはコンパイル後にコメントとして残るか残らないか。
- 「/* */」のコメントはコンパイル後にも残る。
- 「//」のコメントはコンパイル後には残らない。
ということで、コメントも使い分けすると便利。上のサンプルでもコンパイル後には「//」コメントの部分はなくなっています。
但し、アウトプットスタイルが「compressed」の場合はどちらのコメントも残らない。
「compressed」でも残したいコメントがある場合は、
/*! コメント*/
のように、「/*」直後に「!」を入れるとコメントが残ります。
また、コメントの中身を日本語で書きたい場合は必ず頭に「@charset "utf-8";」が必要です。それがないと文字化けしちゃいました。「@charset」のあとに@importが続く場合は、読み込まれるファイルにも影響する模様。
Sassの勉強 関連記事
- Sassの勉強 #00 もっかい最初からやり直そうSassの巻
- Sassの勉強 #01 Sassとは何か?~環境構築
- Sassの勉強 #02 Sassの基本的な機能「ネスト」
- Sassの勉強 #03 Sassの基本的な機能「変数」
- Sassの勉強 #04 Sassの基本的な機能「演算」
- Sassの勉強 #05 Sassの基本的な機能「@import」
- Sassの勉強 #06 スタイルの継承ができる「@extend」
- Sassの勉強 #07 柔軟なスタイル定義が出来る「@mixin」
- Sassの勉強 #08 制御構文(条件分岐・繰り返し)
- Sassの勉強 #09 @at-root
- Sassの勉強 #10 Sassの勉強 #10 関数一覧(Ver.3.4) と自作関数
