在 Sass 中修改选择器的中间(添加/删除类等) [英] Modifying the middle of a selector in Sass (adding/removing classes, etc.)

查看:14
本文介绍了在 Sass 中修改选择器的中间(添加/删除类等)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的菜单中有以下用于样式链接的 SCSS:

I have the following SCSS for styling links in my menu:

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

    ul.opened {
        li {
            a {
                color: green
            }
        }
    }
}

这会生成以下(正确的)CSS:

Which generates the following (correct) CSS:

nav ul li a {
  color: red;
}
nav ul.opened li a {
  color: green;
}

我尝试修改我的 JavaScript 以将类应用于导航元素,并在 Sass 中使用 selector-append() 来附加类.但这似乎以错误的顺序进行附加(如果参数颠倒,则将类附加到最后一个元素!):

I tried modifying my JavaScript to apply the class to the nav element instead, and use selector-append() in Sass to append the class. But that seems to do the appending in the wrong order (and if the arguments are reversed, the class is appended to the last element!):

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() 方法)?

Is there a way the SCSS can be rewritten so that the class can be correctly appended without having to duplicate selectors (similar to the selector-append() method)?

推荐答案

简答

由于我们要替换的元素有一个唯一的名称,所以我们要查找的是:

The short answer

Since the element we want to replace has a unique name, what we're looking for is this:

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

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

长答案

操作选择器是非常肮脏的,除非你绝对必须这样做,否则我建议不要这样做.如果您通过指定诸如 table tr tdul li 之类的内容来过度限定选择器,那么首先要简化:tr 和 ul 在这些选择器中都是多余的(除非您重新尝试避免在有序列表下设置样式元素).调整你的嵌套更简单,等等.

The long answer

Manipulating selectors is extremely dirty, and I would advise against it unless you absolutely had to. If you're overqualifying your selectors by specifying things like table tr td or ul li, then start by simplifying: tr and ul are both redundant in these selectors (unless you're trying to avoid styling elements under an ordered list). Adjust your nesting to be simpler, etc.

从 Sass 版本 3.4 开始,有 2 个重要功能允许您修改选择器.

Starting with Sass version 3.4, there are 2 important features that allow you to modify selectors.

例子:

.foo ul > li a, .bar {
    $sel: &;
    @debug $sel;
}

你总是会得到一个字符串列表,因为选择器可以用逗号链接在一起,即使你只有一个选择器.

You'll always get a list of list of strings because selectors can be chained together with a comma, even when you have only one selector.

.foo ul > li a, .bar { ... }
 (1  2  3  4 5), (1)

您会注意到这里计算了后代选择器(Sass 中的列表可以是空格或逗号分隔).记住这一点非常重要.

You'll note that the descendant selector is being counted here (lists in Sass can be either space or comma delimited). This is extremely important to remember.

selector-replace()函数在以下情况下不起作用:

The selector-replace() function does not work in the following cases:

  • 您要替换的选择器不是唯一的(例如.ul ul li)
  • 您要插入一个或多个选择器(例如.ul ul li -> ul ul ul li)
  • 你想移除一个选择器(例如ul > li -> ul li)
  • The selector you want to replace is not unique (eg. ul ul li)
  • You want to insert one or more selectors (eg. ul ul li -> ul ul ul li)
  • You want to remove a selector (eg. ul > li -> ul li)

在这种情况下,您需要遍历选择器,并且需要知道要修改哪个位置.以下函数将使用 call() 函数.

In this case, you'll need to loop over the selectors and you'll need to know which position you want to modify. The following function will take a function and apply it to a specific position in your selector using the magic of the 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 个参数:原始选择器和您想要附加到它的选择器.使用简单的插值来完成这项工作.

Append a class (when the selector isn't unique or you don't know its name)

The function we need here takes 2 arguments: the original selector and the selector you'd like to append to it. Uses simple interpolation to do the job.

@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 个参数:原始选择器和您要在其之前插入的选择器.

Insert a selector

This function also takes 2 arguments: the original selector and the selector you'd like to insert before it.

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

移除一个选择器

删除选择器就像用空字符串替换选择器一样简单.

Remove a selector

Removing a selector is as simple as replacing your selector with an empty string.

@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

选择器只是一个列表.任何列表操作函数都可以使用它,您可以循环访问它以根据需要对其进行修改.


TL;DR

Selectors are just a lists. Any list manipulation functions will work on it and you can loop over it to modify it as necessary.

是的,除非您真的真的需要,否则不要这样做.如果您决定仍然需要它,我已将这些函数打包到 selector-nth 库中.

So yeah, don't do it unless you really really really need to. If you've decided you still need it, I've packaged these functions up into the selector-nth library.

这篇关于在 Sass 中修改选择器的中间(添加/删除类等)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆