在 Sass 中,如何引用父项选择器并排除任何祖父项?

In Sass, How do you reference the parent selector and exclude any grandparent?

提问人:Cato Johnston 提问时间:7/27/2012 更新时间:6/27/2018 访问量:7758

问:

我有以下 sass 代码:

.class{
    label{
        color:#fff;
        .disabled &{color:#333; }
    }
}

哪个输出

.disabled .class label

有没有办法在不包含任何祖父选择器的情况下输出父选择器?这样:

.disabled label
飒爽

评论


答:

6赞 hopper 7/27/2012 #1

据我所知,在 SASS 中,当使用父引用时,无法从祖先选择器中进行选择。但是,对于您的代码,稍作重组就可以得到相同的结果:

label {
    .class & {
        color: #fff;
    }

    .disabled & {
        color:#333;
    }
}

编译为:

.class label {
  color: #fff; }
.disabled label {
  color: #333; }
-1赞 cimmanon 2/15/2016 #2

父选择器始终是对上一个嵌套级别的整个已解析选择器的引用。没有“父”或“祖父母”的概念,尤其是当连接选择器或在最后使用父选择器时会使水变浑浊。

免责声明:除非您真的需要,否则我不建议这样做

从 Sass 3.4 开始,您可以通过使用作为变量来提取选择器的某些部分。以这种方式使用时,您将获得字符串列表列表(可以循环等)。&

提取选择器的部分或切片

此函数使用与 string-slice 函数相同的参数样式:

@function selector-slice($sel, $start: 1, $end: -1) {
    $collector: ();
    @each $s in $sel {
        // calculate our true start and end indices when given negative numbers
        $_s: if($start > 0, $start, length($s) + $start + 1);
        $_e: if($end > 0, $end, length($s) + $end + 1);
        $c: ();
        @for $i from $_s through $_e {
            $c: append($c, nth($s, $i));
        }
        // prevent duplicates from creeping in
        @if not index($collector, $c) {
            $collector: append($collector, $c);
        }
    }
    @return $collector;
}

/* complex example */
.one-a, .one-b {
    two {
        three {
            color: red;

            &:before {
                @at-root #{selector-slice(&, 2, 3)} {
                    color: green;
                }
            }
        }
    }
}

/* your example */
.class {
    label {
        color:#fff;
        @at-root #{selector-slice(&, -1, -1)} {
            .disabled & {
                color:#333;
            }
        }
    }
}

输出:

/* complex example */
.one-a two three, .one-b two three {
  color: red;
}
two three:before {
  color: green;
}

/* your example */
.class label {
  color: #fff;
}
.disabled label {
  color: #333;
}

作为额外的奖励,您可以使用此函数通过在较小的索引之前传入较大的索引来颠倒选择器的顺序。

.one-a, .one-b {
    two {
        three {
            color: red;

            &:before {
                @at-root #{selector-slice(&, 3, 2)} {
                    color: green;
                }
            }
        }
    }
}

输出:

.one-a two three, .one-b two three {
  color: red;
}
three:before two {
  color: green;
}

相关:在 Sass 中修改选择器的中间(添加/删除类等)

将一个类替换为另一个类

或者,如果您要做的是将一个类替换为另一个类,则可以使用标准库中的函数。selector-replace

.class {
    label {
        color:#fff;
        @at-root #{selector-replace(&, '.class', '.disabled')} {
            color:#333;
        }
    }
}

输出:

.class label {
  color: #fff;
}
.disabled label {
  color: #333;
}
6赞 Kiss 6/27/2018 #3

即使漏斗没有错误,您实际上也可以选择带有变量的祖父。

你可以通过这个实现你想要的:

.class{
    label{
        color:#fff;

        $selector: nth(&,1);
        $direct-parent: nth($selector, length($selector));

        @at-root #{$direct-parent} {
          .disabled &{color:#333; }
        };
    }
}

这将生成这个 css:

.class label {
  color: #fff;
}
.disabled label {
  color: #333;
}