點燈坊

失くすものさえない今が強くなるチャンスよ

如何使用 Class Composition 組合 CSS ?

Sam Xiao's Avatar 2021-01-16

CSS 允許我們將重複 Property 抽出成獨立 Class,然後 HTML Element 再以 Class Composition 完成我們要的視覺效果。

Version

CSS 3

Before Refactoring

class000

各 item 的 font-sizefont-weight 相同,但 color 不同。

<template>
  <div class="fpjs">FP in JavaScript</div>
  <div class="haskell">Programming Haskell</div>
  <div class="spjs">Speaking JavaScript</div>
</template>

<style scoped>
.fpjs {
  font-size: 20px;
  font-weight: normal;
  color: #f00;
}

.haskell {
  font-size: 20px;
  font-weight: normal;
  color: #0f0;
}

.spjs {
  font-size: 20px;
  font-weight: normal;
  color: #00f;
}
</style>

第 8 行

.fpjs {
  font-size: 120%;
  font-weight: normal;
  color: #f00;
}

.haskell {
  font-size: 120%;
  font-weight: normal;
  color: #0f0;
}

.spjs {
  font-size: 120%;
  font-weight: normal;
  color: #00f;
}

我們發現 fpjshaskellspjs 有不少相同 property:font-sizefont-weight,如此違反 DRY,將來維護 CSS 會有困難。

After Refactoring

<template>
  <div class="title fpjs">FP in JavaScript</div>
  <div class="title haskell">Programming Haskell</div>
  <div class="title spjs">Speaking JavaScript</div>
</template>

<style scoped>
.title {
  font-size: 20px;
  font-weight: normal;
}

.fpjs {
  color: #f00;
}

.haskell {
  color: #0f0;
}

.spjs {
  color: #00f;
}
</style>

第 7 行

.title {
  font-size: 120%;
  font-weight: normal;
}

將相同的 property: font-sizefont-weight 抽出成 title class。

13 行

.fpjs {
  color: #f00;
}

.haskell {
  color: #0f0;
}

.spjs {
  color: #00f;
}

不同的 property 維持在原本 fpjshaskellspjs class。

第 2 行

<div class="title fpjs">FP in JavaScript</div>

因此 element 就必須組合 titlefpjs 兩個 class,中間以 空白 間隔即可。

Conclusion

  • CSS 雖然主要目的在處理視覺部分,但並不表示 CSS 不需維護,因此原本 ECMAScript 需要注意的部分,CSS 仍要注意,尤其是 DRY,應避免 copy paste
  • 如同 FP 的核心 Function Composition,CSS 的核心亦是 Class Composition。雖然 CSS 名為 class,其實與 OOP 的 class 不同,但重點仍是 composition,應該以 compose class 開發,避免以 override class 處理