前回は効率的な制作環境を作るために、Gruntについて紹介しました。今回はCSSを効率よく書くことができるSassについて紹介したいと思います。
Sassを使い始めて1年ほど経ちますが、その便利さに、今ではコーディングをする上で欠かせなくなりました。
CSSの場合は、同じスタイルを何度も定義したり、プロパティの変更の修正が面倒だったりします。
Sassを使うと、CSSでは面倒なことを解決できるだけでなく、変数が利用できたり、スタイルの使い回しができたり、for文や四則演算まで使えます! それらを使いこなせば、CSSをより便利で効率的に書くことが出来る。CSS設計もしやすくなります。CSSのパワーアップさせた言語、それがSass!のような感じです。
今回の記事ではSassの機能面について重点を絞って紹介したいと思います。こんなことができたらいいのに...とお悩みの方、リファレンスとしてお使いいただければ!
なお、SassのGruntを使ったコンパイルについては、こちらをご覧ください。
Sassで最も利用する機能がネスト(入れ子)です。記述が入れ子になっているため、HTML構造の理解やセレクタの特定が簡単にできます。CSSの記述も減り、どこに何のプロパティが書いてあるかが見やすくなるため、可読性とメンテナンスが向上します。
#contents {
.unitA {
float: left;
margin-bottom: 20px;
width: 400px;
text-align: center;
text-decoration: none;
font-family: sans-serif;
.modA {
padding: 10px;
}
}
.unitB {
float: right;
width: 200px;
.modA {
display: block;
margin-bottom: 20px;
padding: 10px;
}
}
}
#contents .unitA {
float: left;
margin-bottom: 20px;
width: 400px;
text-align: center;
text-decoration: none;
font-family: sans-serif;
}
#contents .unitA .modA {
padding: 10px;
}
#contents .unitB {
float: right;
width: 200px;
}
#contents .unitB .modA {
display: block;
margin-bottom: 20px;
padding: 10px;
}
Sassでも、CSSと同様に外部のSassファイルをインポートすることができます。
@import url("base.scss");
@import url("layout.scss");
Sassファイルをコンパイルしたくない場合、Sassファイルの頭に、_(アンダースコア)をつけると出力されなくなります。Sassファイルは分割して、出力する際に一つのCSSにまとめることも可能です。
_base.scss _layout.scss
コンパイルするSassファイルに、インポート方法は下記の通りです。
@import "base.scss"; @import "layout.scss";
Sassには、独自のコメントの記述方法が用意されています。
// Sassのコメント
このの形式で記述すると、コンパイルされたCSSファイルにコメントが出力されません。また、CSSで使用している通常のコメントも使うことができます。こちらは、コンパイルされたCSSファイルに出力されます。
#contents {
.unit {
// CSSにコメントは出力されません
/* CSSにコメントが出力されます */
background: #000;
}
}
#contents .unit {
/* CSSにコメントが出力されます */
background: #000;
}
&(アンパサンド)を使用すると、親セレクタや疑似クラスを参照することができます。同じ入れ子内に指定するので、可読性が高くなります。
#contents {
.btn {
color: #fff;
&:hover {
color: #000;
}
}
&.mb10 {
margin-bottom: 10px;
}
> li {
&:first-child {
color: #000;
}
&:last-child {
color: #fff;
}
}
}
#contents .btn {
color: #fff;
}
#contents .btn:hover {
color: #000;
}
#contents.mb10 {
margin-bottom: 10px;
}
#contents > li:first-child {
color: #000;
}
#contents > li:last-child {
color: #fff;
}
変数を利用すると同じ色や数値などの値を使い回しすることできます。また、共通の値をプロパティにセットしておけば、変数の値を変更するだけでプロパティの修正ができます。
$widthA: 400px;
$widthB: 200px;
$colorA: #000;
$colorB: #fff;
#contents {
.unitA {
width: $widthA;
color: $colorA;
}
.unitB {
width: $widthB;
color: $colorB;
}
}
#contents .unitA {
width: 400px;
color: black;
}
#contents .unitB {
width: 200px;
color: white;
}
インターポレーションを使用すると、値を参照するとエラーになってしまう箇所でも使用することができます。画像パス等を変数で用意しておけば、変更があってもいちいち画像パスを変更する必要がありません。
$imageDir:'../images/';
$value: 1;
#contents {
background: url('#{$imageDir}bg_png.png') no-repeat center center;
&:nth-child(#{$value}) {
margin-bottom: 0;
}
}
#contents { background: url("../images/bg_png.png") no-repeat center center; }
#contents:nth-child(1) { margin-bottom: 0; }
プログラミング言語と同様に四則演算が利用可能です。Widthの計算などで電卓を叩く必要がありません。
$unitW:400px;
$unitPd:20;
#contents {
width: 400 + 200px;
.unit {
width: $unitW - $unitPd * 2;
}
}
#contents {
width: 600px;
}
#contents .unit {
width: 360px;
}
指定した条件に応じてスタイルを変えた場合は、if文を使います。条件分岐は、比較演算子や条件演算子を用いて書きます。
条件演算子は、JavaScriptなどで利用できる||や&&は利用できないので、and・or・notを利用します。
$isWebFont: true;
$isWidth:true;
$isHeight:true;
$fontRoboto: "Roboto", sans-serif;
$contentH:200px;
@if $isWebFont {
#contents {
font-family: $fontRoboto;
@if $isHeight and $isWidth {
height: $contentH;
}
}
} @else {
#contents {
font-family: sans-serif;
}
}
#contents {
height: 200px;
font-family: "Roboto", sans-serif;
}
繰り返しの処理は、for・while・eachの3種類があります。
forの構文には種類が2つあり、throughとtoでは処理の内容がことなります。
$length:3;
// 指定の値を繰り返す
@for $i from 1 through $length {
.titleA_#{$i} {
margin-bottom: 10px;
}
}
// 指定した値未満を繰り返す
@for $i from 1 to $length {
.titleB_#{$i} {
margin-bottom: 10px;
}
}
.titleA_1 { margin-bottom: 10px; }
.titleA_2 { margin-bottom: 10px; }
.titleA_3 { margin-bottom: 10px; }
.titleB_1 { margin-bottom: 10px; }
.titleB_2 { margin-bottom: 10px; }
条件式に当てはめて処理を行う場合はwhile文を使用します。for文より柔軟な処理ができます。
$i:1;
$length:20;
@while $i <= $length {
.title_#{$i} {
$path:'../images/ttl_' + $i + 'png';
background: url('#{$path}') no-repeat center center;
}
$i: $i + 1;
}
.title_1 { background: url("../images/ttl_1png") no-repeat center center; }
.title_2 { background: url("../images/ttl_2png") no-repeat center center; }
.title_3 { background: url("../images/ttl_3png") no-repeat center center; }
.title_4 { background: url("../images/ttl_4png") no-repeat center center; }
.title_5 { background: url("../images/ttl_5png") no-repeat center center; }
.title_6 { background: url("../images/ttl_6png") no-repeat center center; }
.title_7 { background: url("../images/ttl_7png") no-repeat center center; }
.title_8 { background: url("../images/ttl_8png") no-repeat center center; }
.title_9 { background: url("../images/ttl_9png") no-repeat center center; }
.title_10 { background: url("../images/ttl_10png") no-repeat center center; }
.title_11 { background: url("../images/ttl_11png") no-repeat center center; }
.title_12 { background: url("../images/ttl_12png") no-repeat center center; }
.title_13 { background: url("../images/ttl_13png") no-repeat center center; }
.title_14 { background: url("../images/ttl_14png") no-repeat center center; }
.title_15 { background: url("../images/ttl_15png") no-repeat center center; }
.title_16 { background: url("../images/ttl_16png") no-repeat center center; }
.title_17 { background: url("../images/ttl_17png") no-repeat center center; }
.title_18 { background: url("../images/ttl_18png") no-repeat center center; }
.title_19 { background: url("../images/ttl_19png") no-repeat center center; }
.title_20 { background: url("../images/ttl_20png") no-repeat center center; }
配列の要素に対して繰り返しの処理を行う場合は、eachを利用します。
while文などと組み合わせて、より効率的にスタイルを定義することができます。
$spotList: 'milano', 'roma', 'sicilia';
$imageDir: '../images/';
@each $spot in $spotList {
.#{$spot} {
$i:1;
$length:3;
@while $i <= $length {
$path: $imageDir + $spot + '/ttl_' + $i + '.png';
.title_#{$i} { background: url('#{$path}') no-repeat center center; }
$i: $i + 1;
}
}
}
.milano .title_1 { background: url("../images/milano/ttl_1.png") no-repeat center center; }
.milano .title_2 { background: url("../images/milano/ttl_2.png") no-repeat center center; }
.milano .title_3 { background: url("../images/milano/ttl_3.png") no-repeat center center; }
.roma .title_1 { background: url("../images/roma/ttl_1.png") no-repeat center center; }
.roma .title_2 { background: url("../images/roma/ttl_2.png") no-repeat center center; }
.roma .title_3 { background: url("../images/roma/ttl_3.png") no-repeat center center; }
.sicilia .title_1 { background: url("../images/sicilia/ttl_1.png") no-repeat center center; }
.sicilia .title_2 { background: url("../images/sicilia/ttl_2.png") no-repeat center center; }
.sicilia .title_3 { background: url("../images/sicilia/ttl_3.png") no-repeat center center; }
extendを利用すると、指定したセレクタのスタイルを継承することができます。AのスタイルをBでも利用する場合にはextendを使うことによって、AのスタイルをBに適用させることができます。
.unitA {
margin: 10px;
padding: 10px;
}
.unitB {
@extend .unitA;
position: relative;
display: block;
}
.unitC {
@extend .unitB;
text-align: center;
font-weight: bold;
}
.unitD {
background: #000;
color: #000;
}
// 複数のextendも可能
.unitE {
@extend .unitC;
@extend .unitD;
}
.unitA, .unitB, .unitC, .unitE {
margin: 10px;
padding: 10px;
}
.unitB, .unitC, .unitE {
position: relative;
display: block;
}
.unitC, .unitE {
text-align: center;
font-weight: bold;
}
.unitD, .unitE {
background: #000;
color: #000;
}
プレースホルダーセレクタを利用するには、頭に%を指定します。
%style {
// プロパティが入ります。
}
プレースホルダーセレクタはextend専用のものなので、コンパイルした際にCSSに出力されません。
%unit-base {
margin: 10px;
padding: 10px;
}
.unitA {
@extend %unit-base;
color: #000;
}
.unitB {
@extend %unit-base;
color: #fff;
}
.unitA, .unitB {
margin: 10px;
padding: 10px;
}
.unitA { color: #000; }
.unitB { color: #fff; }
mixinを利用すると、スタイルをまとめて使うことができます。引数も利用できるので、引数に応じて柔軟なスタイルを定義することができます。
mixinを作成する上で、Bourbonなどを参考にして作ると良いと思います。extendと違って「特定のスタイルを定義するためもの」なので、自分のよく使うスタイル(clearfixの定義やフォントのrem指定など)をライブラリ化しておけば、様々なケースで使い回しができます。
@mixin clearfix() {
zoom: 1;
&:after {
display: table;
clear: both;
content: "";
}
&:before {
display: table;
content: "";
}
}
@mixin fontsize($size) {
font-size: $size * 1px;
font-size: ($size / 10) * 1rem;
}
.unit {
@include fontsize(14);
@include clearfix();
}
.unit {
font-size: 14px;
font-size: 1.4rem;
zoom: 1;
}
.unit:after {
display: table;
clear: both;
content: "";
}
.unit:before {
display: table;
content: "";
}
Sassの便利な機能を使っていくと、CSSでめんどくさいと思ってたことを簡略化することが出来ます。慣れてくると作業効率が上がるので、コーディングスピードが上がり、実務時間に余裕が出来るので、CSSの設計のほうに時間をかけることが出来るようになります。
下記のリンクはSassやCSSの設計をするときに参考になったページです。
Sassの理解を深める際には、書籍「Web制作者のためのSassの教科書 これからのWebデザインの現場で必須のCSSメタ言語」が非常に参考になります。Sassの基本的な機能の使い方や現場で使える使えるノウハウ、Compassについての解説など、Sassを学ぶ上で必要な情報を得ることができます。興味がある方は、ぜひ読んでみてください。
繰り返しになりますが、Sassを使うと、コーディングを効率化することができます。僕の場合はGruntなどを併せて利用して、効率的な制作環境を作っています。Gruntについて興味がある方は、是非こちらの記事も読んでみてください。