樣式
您的元件範本會渲染到其陰影根目錄。您新增至元件的樣式會自動限定範圍到陰影根目錄,且只會影響元件陰影根目錄中的元素。
陰影 DOM 為樣式化提供強大的封裝。如果 Lit 沒有使用陰影 DOM,您就必須非常小心,不要意外地樣式化元件外部的元素,無論是元件的祖先還是子元件。這可能需要寫很長、使用起來很麻煩的類別名稱。透過使用陰影 DOM,Lit 確保您寫入的任何選擇器都只會套用至 Lit 元件陰影根目錄中的元素。
將樣式新增至您的元件
「將樣式新增至您的元件」的永久連結您可以使用標記範本文字 css
函式在靜態 styles
類別欄位中定義範圍樣式。以這種方式定義樣式可實現最佳效能
您新增至元件的樣式會使用陰影 DOM 進行範圍化。如需快速總覽,請參閱陰影 DOM。
靜態 styles
類別欄位的值可以是
單一標記範本文字。
static styles = css`...`;
標記範本文字的陣列。
static styles = [ css`...`, css`...`];
靜態 styles
類別欄位幾乎總是將樣式新增至元件的最佳方式,但有些使用案例無法以這種方式處理 — 例如,自訂每個執行個體的樣式。如需新增樣式的替代方式,請參閱在範本中定義範圍樣式。
在靜態樣式中使用表達式
「在靜態樣式中使用表達式」的永久連結靜態樣式會套用至元件的所有執行個體。CSS 中的任何表達式都會執行一次,然後重複用於所有執行個體。
對於基於樹狀結構或每個執行個體的樣式自訂,請使用 CSS 自訂屬性,以允許元素被主題化。
為了防止 Lit 元件評估潛在的惡意程式碼,css
標籤只允許本身是 css
標記字串或數字的巢狀表達式。
const mainColor = css`red`;
...
static styles = css`
div { color: ${mainColor} }
`;
此限制的存在是為了保護應用程式免受安全性漏洞的侵害,這些漏洞可能會從不受信任的來源(例如 URL 參數或資料庫值)注入惡意樣式,甚至惡意程式碼。
如果您必須在本身不是 css
文字的 css
文字中使用表達式,而且您確信表達式來自完全受信任的來源(例如您自己的程式碼中定義的常數),那麼您可以使用 unsafeCSS
函式包裝表達式
const mainColor = 'red';
...
static styles = css`
div { color: ${unsafeCSS(mainColor)} }
`;
只對信任的輸入使用 unsafeCSS
標籤。 注入未清除的 CSS 是一種安全風險。例如,惡意 CSS 可以透過新增指向第三方伺服器的圖片 URL 來「撥打回家」。
從超類別繼承樣式
「從超類別繼承樣式」的永久連結使用標記範本文字的陣列,元件可以繼承超類別的樣式,並新增自己的樣式
您也可以使用 super.styles
來參照 JavaScript 中超類別的樣式屬性。如果您使用 TypeScript,我們建議避免使用 super.styles
,因為編譯器不一定會正確轉換它。如範例所示,明確參照超類別可避免此問題。
在撰寫打算在 TypeScript 中子類化的元件時,static styles
欄位應明確輸入為 CSSResultGroup
,以允許使用者彈性地使用陣列覆寫 styles
// Prevent typescript from narrowing the type of `styles` to `CSSResult`
// so that subclassers can assign e.g. `[SuperElement.styles, css`...`]`;
static styles: CSSResultGroup = css`...`;
分享樣式
「分享樣式」的永久連結您可以建立匯出標記樣式的模組,在元件之間分享樣式
export const buttonStyles = css`
.blue-button {
color: white;
background-color: blue;
}
.blue-button:disabled {
background-color: grey;
}`;
然後,您的元素可以匯入樣式並將其新增至其靜態 styles
類別欄位
import { buttonStyles } from './button-styles.js';
class MyElement extends LitElement {
static styles = [
buttonStyles,
css`
:host { display: block;
border: 1px solid black;
}`
];
}
在樣式中使用 Unicode 跳脫字元
「在樣式中使用 Unicode 跳脫字元」的永久連結CSS 的 Unicode 跳脫字元序列是反斜線後接四個或六個十六進位數字:例如,項目符號字元的 \2022
。這類似於 JavaScript 已棄用的八進位跳脫字元序列格式,因此在 css
標記範本文字中使用這些序列會導致錯誤。
有兩種將 Unicode 跳脫字元新增至樣式的解決方法
- 新增第二個反斜線(例如,
\\2022
)。 - 使用 JavaScript 跳脫字元序列,以
\u
開頭(例如,\u2022
)。
static styles = css`
div::before {
content: '\u2022';
}
陰影 DOM 樣式總覽
「陰影 DOM 樣式總覽」的永久連結本節簡要概述陰影 DOM 樣式。
您新增至元件的樣式可以影響
樣式化陰影樹狀結構
「樣式化陰影樹狀結構」的永久連結Lit 範本預設會渲染到陰影樹狀結構中。限定於元素陰影樹狀結構範圍的樣式不會影響主文件或其他陰影樹狀結構。同樣地,除了繼承的 CSS 屬性之外,文件層級的樣式不會影響陰影樹狀結構的內容。
當您使用標準 CSS 選擇器時,它們只會比對元件陰影樹狀結構中的元素。這表示您通常可以使用非常簡單的選擇器,因為您不必擔心它們會意外地樣式化頁面的其他部分;例如:input
、*
或 #my-element
。
樣式化元件本身
「樣式化元件本身」的永久連結您可以使用特殊的 :host
選擇器來樣式化元件本身。(擁有或「託管」陰影樹狀結構的元素稱為主機元素。)
若要為主機元素建立預設樣式,請使用 :host
CSS 虛擬類別和 :host()
CSS 虛擬類別函式。
:host
選取主機元素。:host(選擇器)
選取主機元素,但僅限於主機元素符合選擇器時。
請注意,主機元素也會受到陰影樹狀結構外部樣式的影響,因此您應將您在 :host
和 :host()
規則中設定的樣式視為使用者可以覆寫的預設樣式。例如
my-element {
display: inline-block;
}
樣式化元件的子元件
「樣式化元件的子元件」的永久連結您的元件可以接受子元件(例如 <ul>
元素可以有 <li>
子元件)。若要渲染子元件,您的範本需要包含一個或多個 <slot>
元素,如使用 slot 元素渲染子元件中所述。
<slot>
元素在陰影樹狀結構中充當預留位置,其中會顯示主機元素的子元件。
使用 ::slotted()
CSS 虛擬元素,選取透過 <slot>
包含在範本中的子元件。
::slotted(*)
比對所有 slotted 元素。::slotted(p)
比對 slotted 段落。p ::slotted(*)
比對<slot>
是段落元素子系的 slotted 元素。
請注意,只有直接 slotted 子元件可以使用 ::slotted()
進行樣式化。
<my-element>
<div>Stylable with ::slotted()</div>
</my-element>
<my-element>
<div><p>Not stylable with ::slotted()</p></div>
</my-element>
此外,也可以從陰影樹狀結構外部樣式化子元件,因此您應將您的 ::slotted()
樣式視為可以覆寫的預設樣式。
my-element > div {
/* Outside style targetting a slotted child can override ::slotted() styles */
}
ShadyCSS polyfill 中關於 slotted 內容的限制。 如需有關如何在 polyfill 中以友善方式使用 ::slotted()
語法的詳細資訊,請參閱ShadyCSS 限制。
在範本中定義範圍樣式
「在範本中定義範圍樣式」的永久連結我們建議使用靜態 styles
類別欄位,以獲得最佳效能。但是,有時您可能會想在 Lit 範本中定義樣式。有兩種在範本中新增範圍樣式的方式
- 使用
<style>
元素新增樣式。 - 使用外部樣式表新增樣式(不建議)。
這些技術的每一種都有其各自的優點和缺點。
在 style 元素中
「在 style 元素中」的永久連結一般而言,樣式會放置在靜態 styles
類別欄位中;但是,元素的靜態 styles
會每個類別執行一次。有時,您可能需要每個執行個體自訂樣式。為此,我們建議使用 CSS 屬性來建立可主題化元素。或者,您也可以在 Lit 範本中包含 <style>
元素。這些會每個執行個體更新。
render() {
return html`
<style>
/* updated per instance */
</style>
<div>template content</div>
`;
}
ShadyCSS polyfill 中關於每個執行個體樣式化的限制。 使用 ShadyCSS polyfill 不支援每個執行個體樣式化。如需詳細資訊,請參閱ShadyCSS 限制。
表達式和 style 元素
「表達式和 style 元素」的永久連結在 style 元素內使用表達式有一些重要的限制和效能問題。
render() {
return html`
<style>
:host {
/* Warning: this approach has limitations & performance issues! */
color: ${myColor}
}
</style>
<div>template content</div>
`;
}
ShadyCSS polyfill 在表達式方面的限制。由於 ShadyCSS polyfill 的限制,<style>
元素中的表達式不會在 ShadyCSS 中針對每個實例更新。此外,當使用 ShadyCSS polyfill 時,<style>
節點可能不會作為表達式值傳遞。有關更多資訊,請參閱 ShadyCSS 的限制。
評估 <style>
元素內的表達式非常沒有效率。當 <style>
元素內的任何文字發生變化時,瀏覽器必須重新解析整個 <style>
元素,導致不必要的運算。
為了減輕這種成本,請將需要針對每個實例評估的樣式與不需要的樣式分開。
static styles = css`/* ... */`;
render() {
const redStyle = html`<style> :host { color: red; } </style>`;
return html`${this.red ? redStyle : ''}`
匯入外部樣式表(不建議)
連結到「匯入外部樣式表(不建議)」雖然您可以使用 <link>
在您的範本中包含外部樣式表,但我們不建議使用這種方法。相反,樣式應該放在靜態的 styles
類別欄位中。
外部樣式表的注意事項。
- ShadyCSS polyfill 不支援外部樣式表。
- 外部樣式在載入時可能會導致未套用樣式的內容閃爍 (FOUC)。
href
屬性中的 URL 相對於主文件。如果您正在建構應用程式且您的資源 URL 是眾所周知的,這沒有問題,但在建構可重複使用的元素時,請避免使用外部樣式表。
動態類別和樣式
連結到「動態類別和樣式」使樣式動態化的一種方法是在範本中的 class
或 style
屬性中新增表達式。
Lit 提供了兩個指令,classMap
和 styleMap
,方便在 HTML 範本中套用類別和樣式。
有關這些和其他指令的更多資訊,請參閱關於內建指令的文件。
要使用 styleMap
和/或 classMap
匯入
classMap
和/或styleMap
import { classMap } from 'lit/directives/class-map.js';
import { styleMap } from 'lit/directives/style-map.js';
在您的元素範本中使用
classMap
和/或styleMap
有關更多資訊,請參閱 classMap 和 styleMap。
主題化
連結到「主題化」透過一起使用 CSS 繼承和CSS 變數和自訂屬性,可以輕鬆建立可主題化的元素。透過套用 CSS 選取器來自訂 CSS 自訂屬性,可以輕鬆套用基於樹狀結構和每個實例的主題化。以下是一個範例
CSS 繼承
連結到「CSS 繼承」CSS 繼承允許父元素和主機元素將某些 CSS 屬性傳播到它們的後代。
並非所有 CSS 屬性都會繼承。繼承的 CSS 屬性包括
顏色
font-family
和其他font-*
屬性- 所有 CSS 自訂屬性 (
--*
)
有關更多資訊,請參閱 MDN 上的 CSS 繼承。
您可以使用 CSS 繼承在祖先元素上設定樣式,這些樣式會被其後代繼承
<style>
html {
color: green;
}
</style>
<my-element>
#shadow-root
Will be green
</my-element>
CSS 自訂屬性
連結到「CSS 自訂屬性」所有 CSS 自訂屬性 (--custom-property-name
) 都會繼承。您可以使用此功能使您的元件的樣式可以從外部設定。
以下元件將其背景顏色設定為 CSS 變數。如果 DOM 樹中符合祖先的選取器已設定 CSS 變數,則 CSS 變數會使用 --my-background
的值,否則預設為 yellow
class MyElement extends LitElement {
static styles = css`
:host {
background-color: var(--my-background, yellow);
}
`;
render() {
return html`<p>Hello world</p>`;
}
}
此元件的使用者可以使用 my-element
標籤作為 CSS 選取器來設定 --my-background
的值
<style>
my-element {
--my-background: rgb(67, 156, 144);
}
</style>
<my-element></my-element>
--my-background
可以針對 my-element
的每個實例設定
<style>
my-element {
--my-background: rgb(67, 156, 144);
}
my-element.stuff {
--my-background: #111111;
}
</style>
<my-element></my-element>
<my-element class="stuff"></my-element>
有關更多資訊,請參閱 MDN 上的 CSS 自訂屬性。