SASS 和 BEM

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(元素)是 Block 內部的子元素。
  • 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}

雖然外觀一樣,但對開發者來說認知負擔大幅減輕

設計 Modifier 時的安全使用方式

由於 BEM 的 Modifier 代表『狀態』,關鍵在於僅用來覆蓋原本的樣式

 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}

將 Modifier 當作『變更』而非『附加』,設計會更穩定。

Element 巢狀只建議一層

在 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

如果將每個元件一個 block 存成一個檔案,就不容易出錯。

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