简短的回答
由于我们要替换的元素有一个唯一的名称,所以我们要查找的是:
nav {
ul {
li {
a {
color: red;
@at-root #{selector-replace(&, 'ul', 'ul.opened')} {
color: green;
}
}
}
}
}
长答案
操作选择器是非常肮脏的,除非你绝对必须这样做,否则我建议不要这样做。如果您通过指定 table tr td 或 ul li 之类的内容来过度限定选择器,那么首先要简化:tr 和 ul 在这些选择器中都是多余的(除非您试图避免在有序列表下设置元素样式)。调整你的嵌套更简单,等等。
从 Sass 版本 3.4 开始,有 2 个重要功能允许您修改选择器。
例子:
.foo ul > li a, .bar {
$sel: &;
@debug $sel;
}
你总是会得到一个字符串列表,因为选择器可以用逗号链接在一起,即使你只有一个选择器。
.foo ul > li a, .bar { ... }
(1 2 3 4 5), (1)
您会注意到这里计算了后代选择器(Sass 中的列表可以是空格或逗号分隔)。记住这一点非常重要。
当selector-replace() 不起作用时
selector-replace()函数在以下情况下不起作用:
- 您要替换的选择器不是唯一的(例如
ul ul li)
- 您想插入一个或多个选择器(例如
ul ul li -> ul ul ul li)
- 您想删除一个选择器(例如
ul > li -> ul li)
在这种情况下,您需要遍历选择器,并且需要知道要修改哪个位置。以下函数将使用 call() function 的魔力获取一个函数并将其应用于选择器中的特定位置。
@function selector-nth($sel, $n, $f, $args...) {
$collector: ();
@each $s in $sel {
$modified: call($f, nth($s, $n), $args...);
$collector: append($collector, set-nth($s, $n, $modified), comma);
}
@return $collector;
}
Append a class (when the selector isn't unique or you don't know its name)
我们这里需要的函数有 2 个参数:原始选择器和您想要附加到它的选择器。使用简单的插值来完成这项工作。
@function append-class($a, $b) {
@return #{$a}#{$b};
}
.foo, .bar {
ul > li a {
color: red;
@at-root #{selector-nth(&, -2, append-class, '.baz')} {
color: blue;
}
}
}
输出:
.foo ul > li a, .bar ul > li a {
color: red;
}
.foo ul > li.baz a, .bar ul > li.baz a {
color: blue;
}
插入选择器
此函数还接受 2 个参数:原始选择器和您要在其之前插入的选择器。
@function insert-selector($a, $b) {
@return $b $a;
}
.foo, .bar {
ul > li a {
color: red;
@at-root #{selector-nth(&, -2, insert-selector, '.baz')} {
color: blue;
}
}
}
输出:
.foo ul > li a, .bar ul > li a {
color: red;
}
.foo ul > .baz li a, .bar ul > .baz li a {
color: blue;
}
移除一个选择器
删除选择器就像用空字符串替换选择器一样简单。
@function remove-selector($sel) {
@return '';
}
.foo, .bar {
ul > li a {
color: red;
@at-root #{selector-nth(&, -2, remove-selector)} {
color: blue;
}
}
}
输出:
.foo ul > li a, .bar ul > li a {
color: red;
}
.foo ul > a, .bar ul > a {
color: blue;
}
TL;DR
选择器只是一个列表。任何列表操作函数都可以使用它,您可以循环访问它以根据需要对其进行修改。
是的,除非您真的真的需要,否则不要这样做。如果您决定仍然需要它,我已将这些功能打包到 selector-nth library 中。