【问题标题】:Is it possible to write recursive selectors in Sass? [duplicate]是否可以在 Sass 中编写递归选择器? [复制]
【发布时间】:2017-05-11 23:12:19
【问题描述】:

在 Sass 中是否有一种 DRY 方式来编写以下规则?我想要实现的是仅为部分中的第一个 h2 设置 margin-top ,而不管它的嵌套有多深。

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

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

【问题讨论】:

  • 不,只有标记中的第一个 h2 应该受规则影响。
  • 所以,你只希望第一个 h2 是红色的。其他人都不应该受到影响?
  • 对,但是我不知道第一个 h2 嵌套的深度,所以在一个页面中它可能是一层深度 (div > h2) 和另外四层深度 (div > div > div > div > h2).
  • 我认为使用纯 css 是不可能的..
  • div:first-child > h2 不会首先在全球范围内解决这个问题吗?

标签: recursion sass


【解决方案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;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-05
    • 1970-01-01
    • 1970-01-01
    • 2016-07-06
    • 2012-07-21
    • 1970-01-01
    • 2011-03-18
    • 1970-01-01
    相关资源
    最近更新 更多