SASS和BEM

本文将解释SASS和BEM。

我们将通过具体例子,用SASS和BEM解释应对大规模CSS时容易产生混乱和脆弱性的概念及实现方法。

YouTube Video

SASS和BEM

随着文件和页面数量的增加,CSS常常遇到“我不知道这个样式在哪里定义”的困扰,或者“只做了一个小改动,另一个页面的外观就被破坏了”等问题。

这是因为CSS本质上是一种不会强制设计规则的语言。如果继续随意书写,意外的依赖关系就会越来越多。

SASS和BEM是将CSS从即兴编写转变为设计和管理的实用技术,从而避免上述问题。通过结合两者,你可以明确样式的含义,同时提升可读性、可复用性和可维护性。

导致CSS容易变得难以管理的原因

像下面这样的CSS,事后回看时会变得很难理解其行为

 1.title {
 2  font-size: 16px;
 3  color: #333;
 4}
 5
 6.container .title {
 7  font-size: 18px;
 8}
 9
10.sidebar .container .title {
11  color: red;
12}
  • 在此例中,相同的.title根据位置不同而表现不同,因此你很难立即判断这个.title会被应用哪个样式。
  • 这样一来,选择器越深,对父元素的依赖越多,CSS的影响范围就越难预料,调整时也越容易出错。

BEM是一种'通过名称表达角色'的命名规范

BEM代表块(Block)/元素(Element)/修饰符(Modifier),并在类名中包含了该组件的含义及所处的状态。

  • 块(Block) 是一个独立的组件。
  • 元素(Element) 是块的内部元素。
  • 修饰符(Modifier) 代表一种状态或变化。
1.card {}
2.card__title {}
3.card--highlighted {}

采用这种命名规范,你仅通过HTML结构就能推断结构和角色

使用BEM的HTML基本形式

下面是一个通过BEM表示的卡片UI的HTML示例。

1<div class="card card--highlighted">
2  <h2 class="card__title">Title</h2>
3  <p class="card__text">Description</p>
4</div>

仅凭类名,你就能明白这是一个'card组件'、'含有title元素',以及'强调状态'。这正是BEM的最大优点。

但仅用BEM有时会导致CSS冗长。

如果直接将BEM写进CSS,代码量往往会增多。

 1.card {
 2  padding: 16px;
 3}
 4
 5.card__title {
 6  font-size: 18px;
 7}
 8
 9.card__text {
10  font-size: 14px;
11}
12
13.card--highlighted {
14  border: 2px solid orange;
15}

这时,通过使用SASS,可以写出保持结构清晰的有组织的代码

用SASS嵌套自然地表达BEM结构

通过SASS嵌套,你可以将BEM结构直接体现在代码中。

 1.card {
 2  padding: 16px;
 3
 4  &__title {
 5    font-size: 18px;
 6  }
 7
 8  &__text {
 9    font-size: 14px;
10  }
11
12  &--highlighted {
13    border: 2px solid orange;
14  }
15}

&代表父选择器,与BEM命名方式非常契合

由这些SASS生成的CSS

上述SASS会被编译为如下CSS。

 1.card {
 2  padding: 16px;
 3}
 4
 5.card__title {
 6  font-size: 18px;
 7}
 8
 9.card__text {
10  font-size: 14px;
11}
12
13.card--highlighted {
14  border: 2px solid orange;
15}

虽然视觉效果相同,但开发者的认知负担却大大降低

安全使用修饰符的设计建议

由于BEM中的修饰符代表'状态',关键是仅将它们用于重写样式

 1.button {
 2  padding: 8px 12px;
 3  background: #eee;
 4
 5  &--primary {
 6    background: blue;
 7    color: white;
 8  }
 9
10  &--disabled {
11    opacity: 0.5;
12    pointer-events: none;
13  }
14}

如果将修饰符理解为“变化”而非“添加”,设计会更加稳定。

元素嵌套应限制为一级

在BEM中,切忌元素层层嵌套。

1.card {
2  &__header {
3    font-weight: bold;
4  }
5
6  &__body {
7    margin-top: 8px;
8  }
9}

.card__header__title这样的多级元素是一个提示你要考虑分割Block的信号

SASS文件结构示例

最后,这里有一个适用于实际项目的SASS结构示例。

1styles/
2├── base/
3│   └── reset.scss
4├── components/
5│   ├── card.scss
6│   └── button.scss
7├── layout/
8│   └── header.scss
9└── main.scss

如果你将每个组件管理为1个块=1个文件,出错的可能性会更小。

card.scss的例子

 1.card {
 2  padding: 16px;
 3  border: 1px solid #ccc;
 4
 5  &__title {
 6    font-size: 18px;
 7  }
 8
 9  &__text {
10    color: #666;
11  }
12}

由于所有内容都自包含在这个单元中,删除、移动和复用都非常容易

总结

SASS和BEM不仅仅是时髦的技术——它们是让CSS变得可设计的实用方法

  • BEM为类命名赋予意义和角色。
  • SASS让你能在保持结构的同时,轻松编写代码。
  • 两者结合可以让CSS更不易出错。

让我们用未来的自己也能理解的方式来编写CSS吧。

您可以在我们的YouTube频道上使用Visual Studio Code跟随上述文章进行学习。 请也查看我们的YouTube频道。

YouTube Video