是否可以在Sass中编写递归选择器?

时间:2015-10-05 10:16:58

标签: recursion sass

在Sass中编写以下规则是否有干嘛?我想要达到的目的是为一个部分中的第一个h2设置margin-top,而不管它嵌套的深度。

section  {
  $first : '> *:first-child';

    &,
    & #{$first},
    & #{$first} #{$first},
    & #{$first} #{$first} #{$first} {   
        > h2 {
            &:first-child {
                    margin-top: 33px;
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

以下mixin在某种程度上做你想要的。这样做的问题在于,您将创建一大堆样式规则,这些规则需要在您继续进行评估和丢弃时进行,无论您做多少,总会有更深层次的嵌套。这是一个类更有用的情况,甚至可以很好地使用你可用的标签(比如每页只允许一个h2)可以比这更好地解决你的问题,但实质上,这是有效的:

@mixin first-ever-child($select, $limit:20, $root:''){
    $nester: '>*:first-child';
    @for $i from 1 through $limit {
        $root: $root + $nester;
        #{$root + ' ' + $select}{ @content; }
    }
}

body {
    @include first-ever-child(' h2'){
        background: red;
    }
}

上面的mixin默认会输出以下内容(当然是当选择元素时):



body > *:first-child h2 {
  background: red;
}
body > *:first-child > *:first-child h2 {
  background: red;
}
body > *:first-child > *:first-child > *:first-child h2 {
  background: red;
}
body > *:first-child > *:first-child > *:first-child > *:first-child h2 {
  background: red;
}
body > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child h2 {
  background: red;
}
body > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child h2 {
  background: red;
}
body > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child h2 {
  background: red;
}
body > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child h2 {
  background: red;
}
body > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child h2 {
  background: red;
}
body > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child h2 {
  background: red;
}
body > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child h2 {
  background: red;
}
body > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child h2 {
  background: red;
}
body > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child h2 {
  background: red;
}
body > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child h2 {
  background: red;
}
body > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child h2 {
  background: red;
}
body > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child h2 {
  background: red;
}
body > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child h2 {
  background: red;
}
body > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child h2 {
  background: red;
}
body > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child h2 {
  background: red;
}
body > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child > *:first-child h2 {
  background: red;
}




这可以保护您最多20级,但您可以通过限制来扩展它。但请注意,样式规则越多,您的网站获得的速度就越慢。我强烈建议采取另一种方式。

更新

这是一个略微更优化的版本,它甚至可以通过宣布所有规则来提高您的输出。评估仍然相当冗长,但更好:

@mixin first-ever-child($select, $limit:20, $root:''){
    $nester: '>*:first-child';
    $nested: '';
    @for $i from 1 through $limit {
        $root: $root + $nester;
        @if str-length($nested) == 0 {
            $nested: $root;
        } @else {
            $nested: $nested + ', ' + $root;
        }
    }
    #{$nested}{ @content; }
}

body {
    @include first-ever-child(' h2'){
        background: red;
    }
}