SCSS祖先敏感选择器

时间:2019-01-12 16:26:46

标签: css sass

这似乎是某种必须可行的方法,但我只是在任何地方都找不到答案。

是否可以使用SCSS在某个祖先内指定元素的样式变体?

示例:

我想在CSS中使用什么

.parent1 .element,
.parent2 .element {
    /* style for .element in both parents */
}
.parent1 .element {
    /* special style for .element only when in parent1 */
}

我想在SCSS中做什么:

.parent1,
.parent2 {
    .element {
        /* style for .element in both parents */

        [SOME SCSS MAGIC] {
            /* special style for .element only when in parent1 */        
        }
    }
}

否则,我可以放置此样式的最近位置在整个.parent1, parent2代码块的外部,这很方便。

4 个答案:

答案 0 :(得分:1)

使用 @root主体.parent1 .element

  .parent1,
    .parent2 {
        .element {
            /* style for .element in both parents */
              background: yellow;
              color: green;
            @at-root body .parent1 .element {
              color: red;
                /* special style for .element only when in parent1 */
            }
        }
    }

答案 1 :(得分:1)

我建议您不要这样做* ...但是您可以在选择器列表上使用nth-

*使样式的可读性

SCSS

.parent1,
.parent2 {
    .element {
        /* all items in selector list */

        @at-root #{nth(&, 1)} {
          /* first item in selector list */
        }
        @at-root #{nth(&, 2)} {
          /* second item in selector list */
        }
    }
}

CSS输出

.parent1 .element,
.parent2 .element {
  /* all items in selector list */
}

.parent1 .element {
  /* first item in selector list */
}

.parent2 .element {
  /* second item in selector list */
}

更新

要使其更具可读性,您可以创建一个辅助混合器:

@mixin selector-contains($substring) {
    @each $part in & {
        @if str-index($part+'', $substring) { 
            @at-root #{$part}{ @content; } 
        }  
    }
}

.parent1,
.parent2 {
    .element {
        @include selector-contains('.parent1'){
            /* first item in selector list */
        }
        @include selector-contains('.parent2'){
            /* second item in selector list */
        }
        @include selector-contains('.parent'){
            /* all elements */
        }
    }
}

答案 2 :(得分:-1)

您可以使用@at-root指令:

编辑:指出错误后,将&删除并替换为.element

.parent1,
.parent2
{
    .element 
    {
        /* styles for .element in both parents */
        @at-root .parent1 .element
        {
            /* styles for .element only when in parent1 */        
        }
    }
}

答案 3 :(得分:-2)

.parent1,
.parent2 {
    .element {
        /* common styles */
    }
}

.parent1 .element {
    /* parent 1 element overrides */
}

编译为:

.parent1 .element,
.parent2 .element {
  /* common styles */
}

.parent1 .element {
  /* parent 1 element overrides */
}

编辑

或使用mixin容纳常用样式

@mixin commonStyles {
  /* Common to both parent1 & parent 2 */
}

.parent1 {
  .element {
    @include commonStyles;
  }
}

.parent2 {
    .element {
    @include commonStyles;

    /* parent 2 specific styles */
  }
}

编译为:

.parent1 .element {
  /* Common to both parent1 & parent 2 */
}

.parent2 .element {
  /* Common to both parent1 & parent 2 */
  /* parent 2 specific styles */
}

编辑2

如果您将两组样式保持在一起有动力,那么只需使用两个mixin。

@mixin baseStyles {
  /* Common to both parent1 & parent 2 */
}

@mixin modifiedStyles {
  /* parent 2 specific styles */
}

.parent1,
.parent2 {
  .element {
    @include baseStyles;
  }
}

.parent2 {
    .element {
      @include modifiedStyles;
  }
}