Sass使用与号(&)和类型选择器组合父对象


100

我无法在Sass中嵌套。说我有以下HTML:

<p href="#" class="item">Text</p>
<p href="#" class="item">Text</p>
<a href="#" class="item">Link</a>

当我尝试在下面嵌套样式时,出现编译错误:

.item {
    color: black;
    a& {
        color:blue;
   }
}

当它是同一元素的一部分时,如何在父选择器之前引用类型选择器?

Answers:


156

正如Kumar所指出的,自Sass以来,这是可能的3.3.0.rc.1 (Maptastic Maple)

@ at-root指令使一个或多个规则在文档的根目录发出,而不是嵌套在其父选择器下方。

我们可以将@at-root指令插值#{}结合起来以达到预期的结果。

萨斯

.item {
    color: black;
    @at-root {
        a#{&} {
            color:blue;
        }
    }
}

// Can also be written like this.
.item {
    color: black;
    @at-root a#{&} {
        color:blue;
    }
}

输出CSS

.item {
    color: black;
}
a.item {
    color: blue;
}

3
这应该是这个问题的解决方案。
Kayhadrin

这对我不起作用...输出.item a.item出于某种原因而输出。我也尝试过a#{&}自己做,但结果仍然相同。
jaminroe 2015年

@jaminroe您正在使用Libsass吗?它将在3.3中修复
布莱恩2015年

1
@jaminroe似乎在后台使用libsass(node-sass)。如果是这种情况,则需要等到3.3。
Blaine 2015年

1
我有一个稍微强一点的版本来解决,类似,但是有多个类,必须将其附加到标签上 -任何人?
Frank Nocke

29

@at-root,如果你打算扩大最接近的选择了连锁-only方法不能解决问题。举个例子:

#id > .element {
    @at-root div#{&} {
        color: blue;
    }
}

将编译为:

div#id > .element {
    color: blue;
}

如果您需要加入标签.element而不是标签#id怎么办?

Sass中有一个函数selector-unify()可以解决此问题。结合使用@at-root它可以定位.element

#id > .element {
    @at-root #{selector-unify(&, div)} {
        color: blue;
    }
}

将编译为:

#id > div.element {
    color: blue;
}

1
这没有给我预期的结果。在Sass 3.4.11中,这输出到#id > .element #id > div.element { color: blue; }。另一种方法是使用selector_replace#id { > .element { @at-root #{selector-replace(&,'.element', 'div.element')} { color: blue;}}}这是要点,以提高可读性。
布莱恩2015年

@Blaine您发现了一个明显的错误,谢谢。我已经使用有效的解决方案编辑了答案。
本·弗莱明

1
也就是说,这selector-replace也是另一种实现方法,但是它需要知道选择器是什么。该selector-unify方法的好处是可以在混合中使用。
本·弗莱明

很棒的答案。
Senthe

8

对于初学者,(在编写此答案时)没有使用选择器&的 sass语法。如果要执行类似的操作,则需要在选择器和&符之间留一个空间。例如:

.item {
    .helper & {

    }
}

// compiles to:
.helper .item {

}

使用“&”号的另一种方法可能是您(错误地)在寻找:

.item {
    &.helper {

    }
}

// compiles to:
.item.helper {

}

这使您可以使用其他类,ID,伪选择器等扩展选择器。不幸的是,对于您的情况,理论上将其编译为.itema之类的东西,显然不起作用。

您可能只想重新考虑如何编写CSS。是否可以使用父元素?

<div class="item">
    <p>text</p>
    <p>text</p>
    <a href="#">a link</a>
</div>

这样,您可以通过以下方式轻松编写SASS:

.item {
    p {
        // paragraph styles here
    }
    a {
        // anchor styles here
    }
}

(旁注:您应该看一下html。您正在混合单引号和双引号,并将href属性放在p标签上。)


@Lübnah我同意,但我并没有尝试为提高微性能而定义最佳实践。我试图让有人在上href标记p以编写有效的CSS。
2014年

绝对不支持说&.selector是一种不好的做法,完全有一个OP发布了很多用例。
Mike Mellor

@MikeMellor OP编写的,.item { a& }并且没有sass语法(据我所知。我建议他可能正在寻找类似您所描述的与号的语法,该语法在Sass中经常使用。但是,以OP的示例.item { &a }为基础无效的,而且将编译成.itema。就像我在我的回答说,只要有我丢失的东西?
imjared

OP希望.item { a& { ... } }现在可以通过@Blaine用指出.item { @at-root a#{&} { ... } }。关键是,如果您在元素上有一个类很容易做到,.item { &.class { ... } }那么为什么不可以对原始html元素做同样的事情。仅仅因为在OP发布之时没有办法做到这一点并不意味着他不希望该功能实际执行。
Mike Mellor

4

AFAIK如果要同时为类和标记组合“&”号,则需要使用以下语法:

.c1 {
  @at-root h1#{&},
    h2#{&}
    &.c2, {
    color: #aaa;
  }
}

将编译为

h1.c1,
h2.c1,
.c1.c2 {
  color: #aaa;
}

其他用途(例如,使用之前的类@at-root或使用多个@at-root)将导致错误。

希望它会有用


1
我刚刚使用了此功能,这对混入非常有用,例如,您想更改span或div元素的行为
santiago arizti

哇-非常酷:-)所以,#{&}这基本上是在欺骗编译器-否则将来会一直有效!?
Simon_Weaver

@Simon_Weaver sass,里面的所有东西都会#{}被评估。也&表示电流选择器。因此#{&}被评估为.c1
Vahid

但是,您从某种意义上欺骗&不能单独使用;-)
Simon_Weaver

1
@Simon_Weaver请参阅此链接以获取更多示例&
Vahid

3

此功能已安装在最新版本的Sass中, 3.3.0.rc.1(Maptastic Maple)

您需要使用的两个紧密相关的功能是scriptable &(可在嵌套样式中插值以引用父元素)和@at-root指令(将紧随其后的选择器或css块放置在根目录(不会输出的CSS中有任何父母)

有关更多详细信息,请参见此Github问题

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.