Sass v3.3, v4.0 での変更点についてメモ

Sass3.3 がそろそろリリースっぽいので、追加機能・変更点についてうまくまとまった記事があったので、学んでみた。
ちなみに、変更点はこちら

実際に動作を確認するにはpreバージョンのsassをインストールします。

[shell]
gem install sass –pre
sass –watch source_dir:output_dir
[/shell]

で確認できます。

&セレクタに関連する構文の改善

たとえば、以下のようにした場合

[ruby]
$module: ".module";

#{$module}–element {

#{$module}__child { //valid
    color:orange;
}
& #{$module}__child { // valid
    color:orange; 
}
#{$module}__parent & { // valid
    color:yellow;
}
&#{$module}--brother { // invalid in v3.2.x
    color:green;
}

} [/ruby]

最後のブロックは欲しい結果が得られずにエラーになっていた。

この場合、
[css]
.module–element .module__child {
color: orange;
} .module–element .module__child {
color: orange;
} .module__parent .module–element {
color: yellow;
}

/* 以下はエラーで実際に出力されないがv3.3からは修正された */
.module–element.module__parent {
color:green
} [/css]

また、BEMを意識した構造においては

[ruby]
.block {
/* Base stuff / &__child {
/
Sub-element of block */
}

&--modifier {
  /* Variation of block */
}

} [/ruby]

とすることで

[css]
.block { }

.block__child { }

.block–modifier { }
[/css]

という具合に出力されるようになる。
@content(プレースホルダーセレクタ)をつかった場合などで

[ruby]
@mixin respond-to($media, $ie-class:’ie’) {
@media (#{$media}) { @content; }
.#{$ie-class} & { @content; }
}

@include respond-to(‘min-width: 30em’) {
.container { color: red; }
} [/ruby]

とした場合、これまではエラーになっていたが

[css]
@media (min-width: 30em) {
.container {
color: red;
}
} .ie .container {
color: red;
} [/css]

と出力できるようになる。
いままでまどろっこしいパズルをしていた感じから少し解放されそう。

また、セレクターだけでなく値にも適用できて

[ruby]
.hoge, .huge {
$selector: &;
content: $selector
} [/ruby]

[css]
.hoge, .huge {
content: .hoge .huge;
} [/css]

とかもできます。

listの+, - 演算子の実装

リストのでの+演算子はリストへの追加ではなく、文字列連結。
-演算子は-をセパレーターにした文字列文字列連結だったのが
リストの追加、削除(join(), reduce())のようになる。

[ruby]
$a: red, blue;
$b: red, green;

これまで

$a + $b # => red, bluered, green;
$a - $b # => red, blue-red, green;

#v3.3以降
$join: $a + $b; #=> red, blue, green
$reduce: $a - $b; #=> blue, green
[/ruby]

if()へのパーサーの組込み

if() のなかで評価を行うことができる。

[ruby]

@if( condition, true, false ) { }

$a: true;
@if ($a == true, 1, 0) { }

この場合、$a: true;なので 1が評価される。

[/ruby]

minifierの改善

https://github.com/nex3/sass/issues/687

データタイプの追加

https://github.com/nex3/sass/issues/642

これまではkey-valueで設定値を渡したときなどは、

[ruby]
$data: (
color red,
background blue
);

@each $pair in $data {
div {
$first-item : nth($pair, 1);
$second-item : nth($pair, 2);

#{$first-item}: #{$second-item};
}

} [/ruby]

などとしていたのですが、v3.3以降では

[ruby]
$data: (
color: red,
background: blue
);
[/ruby]

という感じJSONっぽいkey-valueがわかりやすい形で渡すことができるそうだ。
これでデバイスごとの設定などがより容易になりそう。
[ruby]
$media-types: (phone: ‘(max-width: 480px)’,
tablet-portrait: ‘(max-width: 767px)’,
tablet-landscape-desktop: ‘(min-width: 768px) and (max-width: 979px)’,
large-desktop: ‘(min-width: 1200px)’,
non-retina: ‘screen and (-webkit-max-device-pixel-ratio: 1)’,
retina: ‘screen and (-webkit-min-device-pixel-ratio: 2)’);

@mixin respond-to($media) {
@if not map-contains($media-types, $media) {
@warn "#{$media} is not a known media type. Using large-desktop instead.";
$media: large-desktop;
}
@media #{map-get($media-types, $media)} {
@content;
}
}

@include respond-to(phone) {
.foo {
background: blue;
}
} [/ruby]

@at-root

@at-rootディレクティブを使用することでネストされてるセレクターがrootレベルで出力される。

たとえば

[ruby]
.foo {
// .foo 内だけど @at-root ディレクティブ内の .bar は rootレベルで出力
@at-root .bar {
color: blue;
}
}

.foo {
// @at-root ディレクティブ内の .bar は rootレベルで出力
// & は 親である .foo を参照
@at-root .bar & {
color: red;
}
}

.foo {
// @at-root で root レベルに .foo を追加したのと同じ
@at-root {
.bar {
color: green;
}
}
} [/ruby]

とすると、それぞれ

[css]
.bar {
color: blue;
}

.bar .foo {
color: red;
}

.bar {
color: green;
}

[/css]

となりSassではネストでコンポーネントをまとめて指定しておき、
出力レベルではネスとさせないことができる。

こちらでもBEMを意識すると

[ruby]
.foo
color: purple
@at-root #{&}__header
color: orange

@at-root #{&}__content
color: black
@at-root #{&}–active
color: green

[/ruby]

[css]
/* 従来なら */

.foo {
color: purple;
} .foo .foo__header {
color: orange;
} .foo .foo__content {
color: black;
} .foo .foo–active {
color: green;
}

/* @at-rootを使用して */
.foo {
color: purple;
} .foo__header {
color: orange;
} .foo__content {
color: black;
} .foo–active {
color: green;
} [/css]

出力がネストされないので上記のような感じ。
冗長な記述しないですみそう。

モジュールとしてファイルをimport

v4.0ではimport周りが大幅に変わるらしい。

  1. @import_once の追加
  2. cssファイルのimportが可能に
  3. 名前空間の追加
  4. 自動でindex.scssまたはindex.sassを検索するようになる
  5. folder単位でのimportパスが使用可能になる
    と大幅に変更されいままでいろいろと面倒だったか点を解決できそう。

参考にしたサイト: http://davidwalsh.name/future-sass

Comments