我有我的菜单样式化链接如下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的类应用到导航元素,而是和使用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可以被重写,使得类可以无需复制选择器(类似于正确所附selector-append()
方法)?
简短的回答
因为我们要替换的元素都有一个唯一的名字,我们正在寻找的东西是这样的:
nav {
ul {
li {
a {
color: red;
@at-root #{selector-replace(&, 'ul', 'ul.opened')} {
color: green;
}
}
}
}
}
长的答案
操作选择是非常脏,我建议不要它,除非你绝对必须。 如果你通过指定的东西像overqualifying您选择table tr td
或ul li
TR和UL在这些选择两个冗余(除非你想避免下一个有序列表的造型元素),然后通过简化启动。 调整你的嵌套更简单等。
与萨斯3.4版开始,有一些让你修改选择2个重要特征。
例:
.foo ul > li a, .bar {
$sel: &;
@debug $sel;
}
你永远得到的字符串列表清单,因为选择可以一起用逗号链接,即使你只有一个选择。
.foo ul > li a, .bar { ... }
(1 2 3 4 5), (1)
你会注意到,后代选择这里正在计数(在萨斯列表可以是空格或逗号分隔)。 记住这一点非常重要。
当selector-replace()
不起作用
在selector-replace()
函数不会在下列情况下工作:
- 要替换的选择不是唯一的(如
ul ul li
) - 要插入一个或多个选择(如
ul ul li
- > ul ul ul li
) - 要删除一个选择器(例如
ul > li
- > ul li
)
在这种情况下,你需要遍历所有的选择,你需要知道你要修改的位置。 下面的函数将采取功能和使用的魔法将其应用到特定位置,在你的选择()函数调用 。
@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;
}
附加一个类(当选择不是唯一的或者你不知道它的名字)
我们这里需要的功能需要两个参数:原来的选择,你想选择要追加到它。 使用简单的插值来完成这项工作。
@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;
}
插入一个选择
该功能还需要两个参数:原来的选择,你想选择之前将其插入。
@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
选择器只是一个列表。 任何列表操作函数将工作就可以了,你可以遍历它根据需要进行修改。
所以是的,除非你真的真的真的需要不这样做。 如果你已经决定,你仍然需要它,我已经打包这些功能成的选择-第n个库 。
我做了解决该问题的混入。
Github上: https://github.com/imkremen/sass-parent-append
例如: https://codepen.io/imkremen/pen/RMVBvq
用法(SCSS):
.ancestor {
display: inline-flex;
.grandparent {
padding: 32px;
background-color: lightgreen;
.parent {
padding: 32px;
background-color: blue;
.elem {
padding: 16px;
background-color: white;
@include parent-append(":focus", 3) {
box-shadow: inset 0 0 0 8px aqua;
}
@include parent-append(":hover") {
background-color: fuchsia;
}
@include parent-append("p", 0, true) {
background-color: green;
}
}
}
}
}
结果(CSS):
.ancestor {
display: inline-flex;
}
.ancestor .grandparent {
padding: 32px;
background-color: lightgreen;
}
.ancestor .grandparent .parent {
padding: 32px;
background-color: blue;
}
.ancestor .grandparent .parent .elem {
padding: 16px;
background-color: white;
}
.ancestor:focus .grandparent .parent .elem {
box-shadow: inset 0 0 0 8px aqua;
}
.ancestor .grandparent .parent:hover .elem {
background-color: fuchsia;
}
.ancestor .grandparent .parent p.elem {
background-color: green;
}