changelog 眺めて、あまり実例が思い浮かばないのもあるけど、一通り試してみた。
parent selector(&) に関して
unquoteなリストを返却するようになった
3.3 ではエラーになっていたけど以下のようにできる
.hoge.fuga .hi.ciao, .yo.hey {
$unquoted-selector: &;
content: $unquoted-selector;
}
.hoge.fuga .hi.ciao, .yo.hey {
content: .hoge.fuga .hi.ciao, .yo.hey;
}
BEMっぽいことも
$separator: __;
@mixin b($block) {
.#{$block} {
@content;
}
}
@mixin e($element) {
@at-root {
@each $e in & {
#{$e}#{$separator+$element} {
@content;
}
}
}
}
.hoge, .huga, .moge {
background: red;
@include e(subelement) {
background: gray;
}
}
.hoge, .huga, .moge {
background: red;
}
.hoge__subelement {
background: gray;
}
.huga__subelement {
background: gray;
}
.moge__subelement {
background: gray;
}
該当の親セレクタがない場合 null
を返す。
こちらも3.3ではエラーでしたが、可能になりました。
@mixin does-parent-exist {
@if & {
&:hover {
color: red;
}
} @else {
a {
color: red;
}
}
}
/* parent exist */
a > .parent-exist {
@include does-parent-exist;
}
/* parent not exist */
a.parent-not-exist {
@include does-parent-exist;
}
a > .parent-exist:hover {
color: red;
}
/* parent not exist */
a.parent-not-exist:hover {
color: red;
}
追加されたselector function
selector-nest($selectors...)
selectorをネストさせる
@mixin nested-context($nested) {
@at-root #{selector-nest(&, $nested)} {
@content;
}
}
.header, .footer {
.nav a {
@include nested-context('.text') {
color: red;
}
}
}
.header .nav a .text,
.footer .nav a .text {
color: red;
}
selector-append($selectors...)
$selecorsのリスト順に追加していく
@mixin append-context($context) {
@at-root {
#{selector-append(&, $context)} {
@content;
}
}
}
.foo, .bar {
color: blue;
@include append-context(':hover') {
color: red;
}
}
.foo, .bar {
color: blue;
}
.foo:hover, .bar:hover {
color: red;
}
また単純に
#{selector-append('.a', '.b', '.c', '.d')} {
content: '.a.b.c.d';
}
とすると順番に追加するだけなので
.a.b.c.d {
content: '.a.b.c.d';
}
となる。
selector-extend($selectors, $extendee, $extender)
- $selectors selectorリスト
- $extendee extendされるselector
- $extender extendするselector
@mixin extend-context($extendee, $extender) {
@at-root {
#{selector-extend(&,$extendee, $extender)} {
@content;
}
}
}
.contet {
.holder {
.show {
color: green;
@include extend-context('.show', '.edit .content-area') {
background-color: black;
}
}
}
}
とかとすると、
.contet .holder .show {
color: green;
}
.contet .holder .show,
.contet .holder .edit .content-area,
.edit .contet .holder .content-area {
background-color: black;
}
となり。.show
を継承もととして、.edit .content-area
が追加されたセレクターが返却されるっぽい感じなのがわかる。
selector-replace($selector, $original, $replacement)
これはそのまま、$selectorの$originalを$replacementに置換。
@mixin replace-context($original, $replace) {
@at-root {
#{selector-replace(&, $original, $replace)} {
@content;
}
}
}
.header{
.nav .blank {
color: green;
@include replace-context('.header', '.footer') {
color: red;
}
}
}
この場合は、.header
を.footer
に置換するので
.header .nav .blank {
color: green;
}
.footer .nav .blank {
color: red;
}
selector-unify($selector1, $selector2)
二つのセレクターの組み合わせたセレクターを返す
selctor1とselector2からできる組み合わせをすべて返すので例えば
@mixin unify-context($selector) {
@at-root {
#{selector-unify(&, $selector)} {
@content;
}
}
}
.note {
input, textarea{
color: black;
@include unify-context('.error') {
color: red;
}
}
}
などとすると
.note input,
.note textarea {
color: black;
}
.note input.error,
.note textarea.error {
color: red;
}
と、全パターンを返してくれる。パターン生成が楽になりそう。
is-superselector($super, $sub)
$super
が $sub
の親要素かどうかを返してくれる
$selectors: '.complete' '.error' '.done';
@each $selector in $selectors {
body#{$selector} {
@if is-superselector(".error", &) {
color: red;
}
@else {
color: gray;
}
}
}
body.complete {
color: gray;
}
body.error {
color: red;
}
body.done {
color: gray;
}
という具合にできるっぽい。これまでより柔軟に分岐できそう。
selector-parse($selector)
string型の変数から簡単にcssを生成できる。
@mixin parse-context($selector, $nth: false) {
@at-root {
@if $nth != false {
#{& nth(selector-parse($selector), $nth)} {
@content;
}
}
@else {
#{& selector-parse($selector)} {
@content;
}
}
}
}
body .foo .bar .baz, .hoge .moge {
color: brown;
}
.content .hoge .moge {
color: gray;
}
うまい実用例が思い浮かばなかったけど、とりあえず。