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

Posted

技术标签:

【中文标题】Sass 使用与号 (&) 和类型选择器组合父级【英文标题】:Sass combining parent using ampersand (&) with type selectors 【发布时间】:2013-06-20 12:31:08 【问题描述】:

我在 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;
   

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

【问题讨论】:

【参考方案1】:

As Kumar points out,自从 Sass 3.3.0.rc.1 (Maptastic Maple) 以来,这已经成为可能。

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

我们可以将@at-root directive 与interpolation # 结合起来以达到预期的结果。

SASS

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

【讨论】:

这应该是这个问题的解决方案。 这对我不起作用...由于某种原因输出到.item a.item。我也试过自己做a#&amp;,结果还是一样。 @jaminroe 你在使用 Libsass 吗?它将是fixed in 3.3。 @jaminroe 看起来像是在底层使用 libsass (node-sass)。如果是这种情况,则需要等到 3.3。 我有一个slightly tougher version of this 来解决,类似,但有多个 类,必须附加到一个标签 – 有人吗? 【参考方案2】:

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

【讨论】:

这并没有给我预期的结果。在 Sass 3.4.11 中,这将输出到 #id &gt; .element #id &gt; div.element color: blue; 。另一种方法是使用selector_replace#id &gt; .element @at-root #selector-replace(&amp;,'.element', 'div.element') color: blue;。 Here's a Gist 以获得更好的易读性。 @Blaine 你发现了一个明显的错误,谢谢。我已经用一个可行的解决方案编辑了我的答案。 也就是说,selector-replace 也是另一种方法,但它需要知道选择器是什么。 selector-unify 方法的好处是可以在 mixins 中使用。 很棒的答案。【参考方案3】:

对于初学者,(在撰写此答案时)没有使用 selector& 的 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 我同意,但我并不想为微观性能提升定义最佳实践。我正在尝试让在p 上添加href 标记的人编写有效的CSS。 绝对不支持说 &.selector 是不好的做法,有大量的用例与 OP 发布的完全一样。 @MikeMellor OP 写了 .item a&amp; 并且没有 sass 语法(据我所知。我建议他可能正在寻找类似你描述的&符号语法的东西,这种语法经常使用在 Sass 中。但是,以 OP 的示例为基础,.item &amp;a 无效,compile to .itema 无效。就像我在回答中所说的那样。我缺少什么吗? OP 想要.item a&amp; ... ,正如@Blaine 用.item @at-root a#&amp; ... 指出的那样,现在可以做到这一点。关键是如果你在元素上有一个类很容易做到.item &amp;.class ... 那么你为什么不能用原始的html元素做同样的事情。仅仅因为在 OP 发布时没有办法做到这一点并不意味着他希望功能实际做到这一点是不正确的。【参考方案4】:

AFAIK 如果你想同时为类和标签组合 & 符号,你需要使用这个语法:

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

将编译为

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

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

希望对你有用

【讨论】:

我刚刚使用了这个,对于想要改变 span 或 div 元素的行为的 mixin 非常有用 哇 - 非常酷 :-) 所以 #&amp; 基本上是在欺骗编译器 - 或者这在未来会一直有效吗!? @Simon_Weaver 在 sass 中,# 中的所有内容都被评估。 &amp; 也表示当前选择器。所以#&amp; 被评估为.c1 但是你在欺骗它,因为 & 单独不起作用 ;-) @Simon_Weaver 请参阅this link 了解更多&amp; 示例【参考方案5】:

此功能已登陆最新版本的 Sass,3.3.0.rc.1(Maptastic Maple)

您需要使用的两个密切相关的功能是可编写脚本的&amp;,您可以在嵌套样式中插入以引用父元素,以及@at-root 指令,它放置紧随其后的选择器或块根处的 css (在输出的 css 中不会有任何父级)

查看Github issue了解更多详情

【讨论】:

以上是关于Sass 使用与号 (&) 和类型选择器组合父级的主要内容,如果未能解决你的问题,请参考以下文章

按位运算符和单与号 [重复]

|=(单管道相等)和 &=(单与号相等)是啥意思

如何使用与号 (&) 替换匹配模式中的字符

在值中使用与号 (&) 时 List.js 不起作用

了解单个与号运算符 (&) 在整数上的行为

了解 PHP &(与号、位与)运算符