修改的Sass选择的中间(添加/删除类等)修改的Sass选择的中间(添加/删除类等)(Modifyi

2019-05-10 10:42发布

我有我的菜单样式化链接如下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()方法)?

Answer 1:

简短的回答

因为我们要替换的元素都有一个唯一的名字,我们正在寻找的东西是这样的:

nav {
    ul {
        li {
            a {
                color: red;

                @at-root #{selector-replace(&, 'ul', 'ul.opened')} {
                    color: green;
                }
            }
        }
    }
}

长的答案

操作选择是非常脏,我建议不要它,除非你绝对必须。 如果你通过指定的东西像overqualifying您选择table tr tdul 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个库 。



Answer 2:

我做了解决该问题的混入。

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;
}


文章来源: Modifying the middle of a selector in Sass (adding/removing classes, etc.)