使用 @supports at-rule(@<at-rule name>) {…},在瀏覽器支援特定 at 規則時,有條件地套用特定 CSS 規則或宣告。這可以包含完整規則,或與 CSS 巢狀結構搭配使用,在特定條件下套用特定宣告。
.foo {
background: var(--accent-color);
@supports at-rule(@property) {
background-image: var(--rainbow-gradient);
animation: sliding-rainbow 1s linear infinite;
}
}
請勿使用 @supports at-rule() 有條件地套用偵測到的 at 規則,而不執行其他操作。
/* BAD: CSS already ignores rules the browser doesn't understand, so this is unnecessary */
@supports at-rule(@starting-style) {
@starting-style {
/* ... */
}
}
在不適合使用 @supports at-rule() 時偵測 at 規則支援
如果瀏覽器不支援 at-rule(),或需要更深入的偵測,請參考下方指引。
先嘗試屬性、值或選取器
@supports 已經可以偵測屬性、值和選取器 (透過 @supports selector(...))。在許多情況下,您可以使用這些功能偵測功能支援,而不必檢查 at 規則本身。
舉例來說,您可以使用 @supports (color: --foo()),而不使用 @supports at-rule(@function) 來偵測自訂函式的支援。
在其他情況下,可能會有僅在支援特定 at 規則時才可用的虛擬類別或虛擬元素,可用於偵測支援。
偵測容器查詢類型
at-rule() 僅允許依名稱偵測 at 規則。不允許偵測其他語法或描述元。
例如,以下做法無效:
@supports at-rule(@container style(--a: 1)) {
/* ... */
}
對於許多類型的容器查詢,您可以使用 container-type 搭配適當的值。例如,@supports (container-type: scroll-state) 用於捲動狀態查詢,或 @supports (container-type: size)container-type: anchoredforanchored()` 查詢。
不過,樣式查詢沒有 container-type。重要事項:請勿嘗試使用 @supports (container-type: style) 偵測樣式查詢支援,因為這不會運作。
您可以改用一律為 true 的樣式查詢:
@container style(--a: 1) or (not (style(--a: 1))) {
/* Rules here will only be applied if style queries are supported */
}
只要屬性名稱或值在兩者中相同,無論使用何種屬性名稱或值,這都會在任何支援樣式查詢的瀏覽器中比對成功。
已註冊的自訂屬性 (@property)
在某些情況下,如果可以將要套用的條件式 CSS 縮減為單一屬性,則可使用專為此目的註冊的自訂屬性:
/* Use a custom property to conditionally include the dash animation */
@property --progress-dash-animation {
syntax: "*";
inherits: false;
initial-value: , progress-dash 3s ease-in-out infinite;
}
.spinner {
/* The dash animation is only included if @property is supported */
animation:
progress-spin var(--_used-spinner-duration) linear infinite
var(--progress-dash-animation, );
}
如需更通用的解決方案,您可以註冊非繼承屬性,並在根元素上將其設為 (空格):
{# Testcase: https://codepen.io/leaverou/pen/KwWzpVr #}
@property --supports-atproperty {
syntax: "*";
inherits: false;
}
:root {
--supports-atproperty: ;
}
body {
/* The background is only applied if @property is supported */
background: var(--supports-atproperty, green);
}
注意:
- 這兩種方法只有在空白字元是可接受的替代方案時才有效。其他情況則需要使用 JS,如下所示。
- 一般用途解決方案仰賴非繼承,因此不適用於根元素的宣告。
只有在不得已的情況下,才使用 JavaScript
如要檢查整個 at 規則,請確認 JavaScript 中是否存在特定介面。舉例來說,如果定義了 globalThis.CSSFunctionRule,則支援 @function。
如需進行更深入的測試 (例如特定前置、巢狀規則、描述元),可以設定測試並檢查剖析方式:
const sheet = new CSSStyleSheet();
sheet.replaceSync(`
@page {
@top-left {
content: "test";
}
}
`);
const SUPPORTS_PAGE_MARGINS = Boolean(sheet.cssRules[0]?.cssRules?.[0]);
重要事項:
- 使用 JS 偵測 CSS 功能支援時,請勿直接從 JS 套用樣式。請改為將類別套用至根元素,並在 CSS 中分支。
- 請注意,即使無法辨識前置詞,系統仍會剖析容器查詢,而且無法從 CSSOM 結構偵測是否支援特定類型的容器查詢。
- 請勿使用
CSS.registerProperty偵測@property的支援情形,因為其支援範圍稍廣。
備用策略
除非這在支援目標範圍內,否則「只能」使用 @supports (at-rule()) 偵測支援範圍比 @supports (at-rule()) 功能本身更窄的 at 規則。
如要根據這項功能推出前提供的 at 規則支援,有條件地套用 CSS,請參閱上一節的指南。
如要偵測 @supports at-rule() 功能本身是否支援,可以使用保證存在於所有支援 @supports at-rule() 的瀏覽器中的 at 規則,例如 @supports at-rule(@media) { ... }。