上村 光星

Sass 3.3で追加された「&」の新機能と@at-rootまとめ解説

dtl_thm_sass10月12日にSass 3.3.0.rc.1が出ました。まだリリース候補ですが、どのような機能が追加されるのかはChangelogにあります。今回は「&」と@at-rootについて解説します。

HTML+CSSの命名規則にBEM方法論、もしくはHTML+CSS向けに派生したMindBEMdingを取り入れる方が増えてきているようです(筆者は使っていませんが…)。「&」の新機能と@at-rootは、このBEMのためといっても過言ではありません。

Sass 3.2の「&」

「&」は親セレクタを参照する特別なキーワードとして、Sass 3.3よりも前からありましたが、擬似クラスや擬似要素、セレクタの連結など、用途が限られていました。

「&」を使って、親のクラス名を子のクラス名の一部にすることはできませんでした。

Sass 3.3の&

Sass 3.3からは「&」をより多くの場所で使うことができるようになりました。 前述の「親のクラス名を子のクラス名の一部にする」には次のようにします。

これをコンパイルすると次のようになります。

「&」はセレクタに使用するだけでなく、変数の値に指定することもできるようになりました。

このようにした場合、$selectorには (“.foo”, (“.bar” “.baz”)) というようにリストとして格納されます(実際にtype-of()で調べると list が返ってきます)。括弧や引用符で囲まれていますが、実際にはそれらは外された状態で使用されます。

これをコンパイルすると次のようになります。

「&」を使ってBEM

では、「&」を使ってBEMっぽく書いてみましょう。

これをコンパイルすると次のようになります。

.block__elementの前の.blockはともかく、.block__element–modifierの一つ前にも.blockが出力されてしまっています…。 次のようにネストを減らして書くことで、これを回避することもできますが、、

この方法だと__elementを何度も書くことになってしまいます。.block__elementの前の.blockを出力しなくてもよいという運用ルールであれば、次に紹介する@at-rootで解決することができます。

@at-root

@at-rootの基本機能は、記述した場所より上のセレクタのネストを解除するというものです。
使い方は次のとおりです。

これをコンパイルすると次のようになります。

.qux .quux { … }の.quxを取り除いて.quux { … }としたい場合は、.quuxの前にも@at-rootを記述します。

では、前節の問題を解決します。

これをコンパイルすると次のようになります。

ようやくすべてフラットにすることができました。

ただ、@at-rootの分だけネストが多くなったのが気になるかもしれません。
ネストを減らしたい方は@at-rootを隠蔽したミックスインを使うことを検討してみてください。

@at-rootの応用

@media内で@at-rootを使用した場合、そのルールセットは@media内に出力されます。

これをコンパイルすると次のようになります。

@mediaの外に.barを出したい場合は、@at-root (without: …)を使います。

@at-root (without: … )

次のように@at-root (without: media)とすると@mediaの外に出すことができます。

コンパイルすると次のようになります。

@mediaの外には出されましたが.foo .bar { … }となってしまいました。.fooを取り除いて.bar { … }としたい場合は、withoutの値にruleを追加します。

これをコンパイルすると次のようになります。

このようにwithoutと後述するwithには、スペース区切りで複数の値を指定することができます。

説明
mediaやsupportなど@ルールを除外する/しない
ruleCSSルールセットを除外する/しない
allすべてを除外する/しない

前述の例では、@at-root(without: media rule)としましたが、必ずドキュメントルートに出力したい場合は(without: all)と記述した方が良いです。

@at-root(without: rule)は@at-rootのみ記述した場合と同じです。推測ですが、@at-rootには初期値として(without: rule)が設定されていると思われます。(without: media)とした場合は、初期値を上書きするので(without: rule media)のようには処理されなかったと考えられます。

また、withoutとwithは同時に指定することはできませんでした。(with: …)を指定した場合も初期値(without: rule)が上書きされてしまうようです。

@at-root(with: … )

では最後に(with: …)ですが、これに指定したもの以外が除外されます。以下にいくつかのサンプルを記載しておきますので、どのように出力されるか確認してみてください。

コンパイルすると次のようになります。

おわりに

「&」の新機能と@at-rootを解説しましたが、いかがだったでしょうか。確かにメリットもありますが、「&」はクラス名の検索がしづらくなりますし、@at-rootは出力後のCSSがどうなるかが想像しにくいケースが出てくるなど、デメリットもあります。筆者としては、これらを利用する場合は用途を限定するなどのルールを設けたいと思いました。

Powered byNTT Communications

tag list

アクセシビリティ イベント エンタープライズ デザイン ハイブリッド パフォーマンス ブラウザ プログラミング マークアップ モバイル 海外 高速化 Angular2 AngularJS Canvas Chrome Cordova CSS de:code ECMAScript Edge Firefox Google Google I/O 2014 HTML5 Conference 2013 html5j IoT JavaScript Microsoft Node.js PhoneGap Polymer React Safari SkyWay TypeScript UI UX W3C W3C仕様 Webアプリ Web Components WebGL WebRTC WebSocket