如何在SASS

时间:2017-06-09 06:05:34

标签: html css sass bem

SASS + BEM在大多数时候都是天堂般的匹配,但是我的共同奋斗是理解如何在使用SASS父选择器时影响其子元素的元素上最好地定义BEM修饰符。

我使用BEM样式语法在SASS中定义了以下组件:

.card {
  background-color: #FFF;

  &__value {
    font-size: 2em;
    color: #000;
  }
}

这很有效,因为SASS的父选择器。它保持相关代码的组织和自包含。

但是当我需要添加一个使用父选择器改变子元素的修饰符时,这个想法很快就崩溃了:

.card {
  padding: 2em;

  &__value {
    font-size: 1.5em;
    color: #000;
  }

  &--big {
    padding: 2.5em;

    &__value {          // Is this going to work?
      font-size: 3em;
    }
  }
}

不。它产生了这个:

.card {
  padding: 2em;
}
.card__value {
  font-size: 1.5em;
  color: #000;
}
.card--big {
  padding: 2.5em;
}
.card--big__value {  // Wrong
  font-size: 3em;
}

以某种方式得到这个选择器会更有意义:

.card--big .card__value {
  font-size: 3em;
}

这样做的原因是,您可以简单地将修饰符添加到顶级元素,并使其影响任何或所有子元素。

我尝试了几种方法:

使用两个结构

.card {
  padding: 2em;

  &__value {
    font-size: 1.5em;
    color: #000;
  }
}

.card--big {
  padding: 2.5em;

  &__value {
    font-size: 3em;
  }
}

这有效(特别是在这个简化的演示中)但是在一个更复杂的组件中有许多修饰符,这可能是一个潜在的难以维护和保持bug。此外,如果可能的话,继续使用SASS父选择器会很好。

为元素

使用变量
.card {
  $component: &;  // Set the variable here

  padding: 2em;

  &__value {
    font-size: 1.5em;
    color: #000;
  }

  &--big {
    padding: 2.5em;

    #{$component}__value {  // Use it here
      font-size: 3em;
    }
  }
}

这很有效。但是将元素定义为变量似乎有点愚蠢。也许这是唯一真正做到这一点的方式......我不确定。是否有更好的选择来构建它?

8 个答案:

答案 0 :(得分:4)

为什么不这样做?

.card {
  padding: 2em;

  &__value {
    font-size: 1.5em;
    color: #000;
  }

  &--big {
    padding: 2.5em;
  }

  &--big &__value {  
    font-size: 3em;
  }
}

答案 1 :(得分:1)

您可以将修改器拆分为不同的结构,但嵌套在.card选择器中,如下所示:

.card {
  padding: 2em;

  &__value {
    font-size: 1.5em;
    color: #000;
  }

  &--big {
    padding: 2.5em;
  }

  &--big &__value {
    padding: 2.5em;
  }
}

反过来会产生这个:

.card {
  padding: 2em;
}
.card__value {
  font-size: 1.5em;
  color: #000;
}
.card--big {
  padding: 2.5em;
}
.card--big .card__value {
  padding: 2.5em;
}

我认为这是一种近乎完美的方式,尽管它并不完美嵌套 我希望这是一个帮助!

答案 2 :(得分:1)

我刚刚找到了一个更好的方法来实现这一点,通过使用变量来存储父选择器的值,您可以在任何嵌套级别使用它!

例如,我将.card选择器存储在$ this变量中,并重新使用它#{$this}

所以这段代码

.card {
  padding: 2em;

  &__value {
    font-size: 1.5em;
    color: #000;
  }
  $this: &;

  &--big {
    padding: 2.5em;

    #{$this}__value {
      font-size: 3em;
    }
  }
}

将编译为

.card {
  padding: 2em;
}
.card__value {
  font-size: 1.5em;
  color: #000;
}
.card--big {
  padding: 2.5em;
}
.card--big .card__value {
  font-size: 3em;
}

这个答案的灵感来自css-tricks上的这篇文章。感谢Sergey Kovalenko

答案 3 :(得分:0)

您的解决方案看起来很不错,但您也可以尝试@at-root

答案 4 :(得分:0)

.card {
  padding: 2em;

  &__value {
    font-size: 1.5em;
    color: #000;
  }

  &--big {
    padding: 2.5em;

    &__value {          // Is this going to work?
      font-size: 3em;
    }
  }
}

您可以通过以下方式获得您想要的结果:

.card {
  padding: 2em;

  &__value {
    font-size: 1.5em;
    color: #000;
  }

  &--big {
    padding: 2.5em;

    .card {
       &__value {          // this would work
          font-size: 3em;
       }
    }
  }
}

答案 5 :(得分:0)

经历同样的问题我构建了一个名为Superbem的库,它基本上是一组SCSS mixins,可以帮助你编写BEM声明方式。看看:

@include block(card) {
    padding: 2em;

    @include element(value) {
        font-size: 1.5em;
        color: #000;
    }

    @include modifier(big) {
        padding: 2.5em;

        @include element(value) {
            font-size: 3em;
        }
    }
}

给你:

.card, .card--big {
    padding: 2em; 
}

.card__value {
    font-size: 1.5em;
    color: #000; 
}

.card--big {
    padding: 2.5em; 
}

.card--big .card__value {
    font-size: 3em; 
}

希望你能发现它有用!

答案 6 :(得分:0)

您可以在此处使用另一种模式。

这将:
 -将实际的卡片修饰符与其元素的修饰符分开
 -将修改后的样式保留在相同元素的选择器中,因此您无需上下滚动代码即可查看正在修改的内容
 -如果您是这样的话,则会阻止更具体的规则出现在不那么具体的规则之上

这是一个例子:

// scss
.card {
  $component: &;

  padding: 2em;

  &--big {
    padding: 2.5em;
  }

  &__value {
    font-size: 1.5em;
    color: #000;

    #{$component}--big & {
      font-size: 3em;
    }
  }
}

/* css */
.card {
  padding: 2em;
}
.card--big {
  padding: 2.5em;
}
.card__value {
  font-size: 1.5em;
  color: #000;
}
.card--big .card__value {
  font-size: 3em;
}

答案 7 :(得分:0)

您可以通过添加一个字符来实现这一点,不需要变量或混合。

&--big { 变成 &--big & {

.card {
  padding: 2em;

  &__value {
    font-size: 1.5em;
    color: #000;
  }

  &--big & {
    padding: 2.5em;

    &__value {          // Is this going to work? (yes!)
      font-size: 3em;
    }
  }
}