Skip to content

2026-07-09

/ 11 分鐘閱讀

/ You Might Not Need a Framework

Web Components 的 CSS 策略與常見問題釐清 ​

上一篇完整說明了 Shadow DOM 的機制,以及它如何解決 template 樣式洩漏到全域的問題。這篇補充幾個相關的實務細節:Declarative Shadow DOM 的現況、如何為 Web Component 定義 CSS,以及幾個常見的概念澄清。

Declarative Shadow DOM:還不夠成熟 ​

Declarative Shadow DOM 是一個讓你直接在 HTML 標記中宣告 Shadow DOM 的方式,不需要透過 JavaScript 的 attachShadow。它的優勢在於伺服器端渲染(Server-Side Rendering)引擎可以在不執行 JavaScript 的情況下,直接在 HTML 輸出中建立 Shadow DOM。

不過截至課程錄製時,這個功能才剛剛在 Safari 中取得支援,整體瀏覽器相容性還不夠完整。因此這門課不使用它,未來等相容性更成熟後,它可能會成為建立 Web Components 更推薦的方式。

為 Web Component 定義 CSS ​

使用 Shadow DOM 的元件不會繼承外部的 CSS,所以需要自己為元件定義樣式。這同樣沒有唯一的做法,幾種可行的選項包含:

  • 使用 CSSOM API:JavaScript 本身有一套操作 CSS 的 API,可以用 JavaScript 建立樣式表並注入 Shadow DOM
  • 在 <template> 中加入 <style> 標籤
  • 在 <template> 中加入 <link> 標籤,引用外部 CSS 檔案
  • 用 Fetch API 載入外部 CSS 檔案,再作為 <style> 注入 Shadow DOM(這個 CSS 檔案也可以事先 prefetch)

課程後面實作時會選擇其中一種方式,但選擇的理由是「這是一種可行的方式」,不代表它一定是最佳解。

template 與 custom element 之間的連結 ​

這個連結不是自動建立的,而是由你作為開發者主動建立。Custom Element 在 connectedCallback 中用 getElementById 或 querySelector 取得指定的 template,然後克隆並使用它。

同一個 template 也可以被多個不同的 custom element 共用,這就是為什麼必須克隆而不是直接使用——每個元件實例需要有自己獨立的 DOM 副本,而不是共享同一份節點。克隆時,template 內部的所有 DOM(包含樣式)都會一起被克隆。

這也再次說明了為什麼 Web Components 被稱為「一組完全獨立的 API 組合」:Custom Elements、HTML Templates 和 Shadow DOM 各自分開,是我們選擇把它們搭配在一起,作為一種設計模式來建立元件。

是否一定要用 class? ​

Custom Element 必須提供一個實作 HTML 介面的物件。在現代 JavaScript 中,最直接的方式是使用 class 語法繼承 HTMLElement。但在技術上並不是只有 class 這條路,JavaScript 也可以用較為老式的方式(修改 prototype 鏈)達到同樣的效果,只是今天看起來有些奇怪。

你也可以自己打造一個迷你框架或函式庫,讓使用者能以函式的方式建立 web components,底層再幫你把物件包裝成符合規格的形式。但這些都是你自己要做的事,瀏覽器並不原生支援函式式的寫法。總結來說,在現代 JavaScript 中,使用 class 是最自然、也是最推薦的方式。

複習 ​

Declarative Shadow DOM 是什麼,它與傳統的 Shadow DOM 建立方式有何不同? ​

Declarative Shadow DOM 允許直接在 HTML 標記中宣告 Shadow DOM,不需要 JavaScript,讓伺服器端渲染引擎可以在不執行 JavaScript 的情況下,直接在 HTML 輸出中建立 Shadow DOM。

為 Web Component 克隆 template 時,會克隆哪些內容? ​

克隆 template 時,template 內部的所有 DOM 都會被克隆,確保每個元件實例都有自己獨立的 Shadow DOM。

有哪些方式可以為使用 Shadow DOM 的 Web Component 添加 CSS? ​

可以使用 CSSOM API、在 template 中加入 style 或 script、在 template 中加入 link 引用外部 CSS,或是用 Fetch API 載入外部 CSS 檔案並注入 Shadow DOM 作為 style。

建立 Web Component 是否一定需要使用 class? ​

class 不是硬性要求,但傳入的物件必須實作 HTML 介面。在現代 JavaScript 中,使用 class 是最推薦的方式,其他方式技術上可行但看起來較不直觀。

template 與 custom element 之間的連結是如何建立的? ​

由開發者手動建立,通常透過 ID 載入 template。同一個 template 可以被多個 custom element 重複使用,這也是為什麼在使用時需要克隆而不是直接共用。

小測驗 ​

Declarative Shadow DOM 是什麼? 一種不需要 JavaScript,直接在 HTML 標記中宣告 Shadow DOM 的方式
如何為 Shadow DOM 添加樣式? 可以使用 CSSOM API 建立樣式表
為 Web Component 克隆 template 時會發生什麼? template 內部所有的 DOM 元素和樣式都會被克隆
建立 Web Component 是否一定需要使用 class? 不一定,但傳入的物件必須實作 HTML 介面
Shadow DOM 的一個關鍵特性是什麼? 它不會繼承元件外部的 CSS

此文章是 FrontendMasters 上的 Vanilla JS: You Might Not Need a Framework 課程筆記

最後更新時間:

Buy Me A Coffee

系列章節 第 20 篇 / 共 32 篇

0 %
MIT Licensed | Copyright © 2025-present Wen-Hsiu's Blog
Photo by Federica Galli on Unsplash