修改Sass中select器的中间(添加/删除类等)
我有我的菜单中的样式链接以下SCSS:
nav { ul { li { a { color: red } } } ul.opened { li { a { color: green } } } }
其中生成以下(正确的)CSS:
nav ul li a { color: red; } nav ul.opened li a { color: green; }
我尝试修改我的JavaScript来将类应用于nav元素,并在Sass中使用selector-append()
来追加类。 但是这似乎是以错误的顺序进行追加(如果参数颠倒过来,则该类将被追加到最后一个元素!):
nav { ul { li { a { color: red; @at-root #{selector-append('.opened', &)} { color: green; } } } } }
输出(不正确!):
nav ul li a { color: red; } .openednav ul li a { color: green; }
是否有一种方法可以重写SCSS,以便类可以正确追加而不必重复select器(类似于selector-append()
方法)?
简短的回答
由于我们要replace的元素具有唯一的名称,因此我们要查找的是:
nav { ul { li { a { color: red; @at-root #{selector-replace(&, 'ul', 'ul.opened')} { color: green; } } } } }
长的答案
操作select器是非常肮脏的,我会build议反对它,除非你绝对必须。 如果通过指定table tr td
或ul li
等选项来过度限定select器,则可以先简化:tr和ul在这些select器中都是多余的(除非您试图避免在有序列表下面使用样式元素)。 调整你的嵌套更简单等
从Sass版本3.4开始,有两个重要的特性允许你修改select器。
- select器function
- 父select器可以存储在一个variables中
例:
.foo ul > li a, .bar { $sel: &; @debug $sel; }
总是会得到一个string列表的列表,因为即使只有一个select器,select器也可以用逗号连接在一起。
.foo ul > li a, .bar { ... } (1 2 3 4 5), (1)
你会注意到后代select器正在计数(在Sass中的列表可以是空格或逗号分隔的)。 这是非常重要的记住。
当selector-replace()
不起作用时
在以下情况下, selector-replace()
函数不起作用:
- 您要replace的select器不是唯一的(例如,
ul ul li
) - 你想插入一个或多个select器(例如,
ul ul li
– >ul ul ul li
) - 你想删除一个select器(例如,
ul > li
– >ul li
)
在这种情况下,您需要循环select器,并且需要知道要修改的位置。 下面的函数将使用call()函数的魔法将一个函数应用到select器中的特定位置。
@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; }
附加一个类(当select器不是唯一的或者你不知道它的名字时)
我们在这里需要的函数需要2个参数:原始select器和select器,你想追加到它。 使用简单的插值来完成这项工作。
@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; }
插入一个select器
这个函数也需要2个参数:你想在它之前插入的原始select器和select器。
@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; }
删除select器
删除select器就像用空stringreplaceselect器一样简单。
@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
select器只是一个列表。 任何列表操作函数都可以在它上面工作,并且你可以循环它来根据需要修改它。
所以是的,除非你确实需要,否则不要这样做。 如果你已经决定你还需要它,我已经将这些函数打包到select器的第n个库中 。