さて、私は一種の回避策を思いつきました。
このアプローチは、意図した機能を単に分離し、実際の階層から独立して管理します。
まず、いくつかの簡単なユーティリティ:
@function slice($list, $from, $into) {
$result: ();
@for $index from $from through $into {
$result: append($result, nth($list, $index));
}
@return $result;
}
@function implode($list, $separator) {
$result: nth($list, 1);
@for $index from 2 through length($list) {
$result: #{$result}#{$separator}#{nth($list, $index)};
}
@return $result;
}
次に根性:
$-class: ();
@function get-class() {
$top: if(length($-class) - 2 < 1, 1, length($-class) - 2);
@return implode(slice($-class, $top, length($-class)), "-");
}
@mixin class($name) {
$-class: append($-class, $name);
.#{get-class()} {
@content;
}
$-class: slice($-class, 1, length($-class) - 1);
}
ここで何が起こるかというと、「グローバル」変数$-class
は、 mixin の呼び出しごとにネスト スタックを維持しますclass
。スタックの上位 3 つの名前を内破することにより、CSS クラス宣言を作成します (必要に応じて、これを完全なスタックに変更できます) 。
したがって、質問の例を複製します。
@include class (foo) {
color: red;
@include class (bar) {
color: blue;
}
}
生産します:
.foo { color: red; }
.foo .foo-bar { color: blue; }
それほど些細な例は次のとおりです。
@include class(list) {
test: "list";
@include class(item) {
test: "item";
@include class(heading) {
test: "heading";
}
@include class(content) {
test: "content";
@include class(graphic) {
test: "graphic";
}
@include class(summary) {
test: "summary";
}
@include class(details) {
test: "details";
}
}
@include class(footing) {
test: "footing";
}
}
}
生産:
.list { test: "list"; }
.list .list-item { test: "item"; }
.list .list-item .list-item-heading { test: "heading"; }
.list .list-item .list-item-content { test: "content"; }
.list .list-item .list-item-content .item-content-graphic { test: "graphic"; }
.list .list-item .list-item-content .item-content-summary { test: "summary"; }
.list .list-item .list-item-content .item-content-details { test: "details"; }
.list .list-item .list-item-footing { test: "footing"; }