ใช้ @supports at-rule(@<at-rule name>) {…} เพื่อใช้กฎหรือการประกาศ CSS บางอย่างแบบมีเงื่อนไขเฉพาะในกรณีที่เบราว์เซอร์รองรับ At-rule บางรายการ
ซึ่งอาจมีกฎทั้งหมด หรือใช้ร่วมกับการฝัง 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-Rule ที่ตรวจพบแบบมีเงื่อนไขและไม่มีอะไรอื่น
/* BAD: CSS already ignores rules the browser doesn't understand, so this is unnecessary */
@supports at-rule(@starting-style) {
@starting-style {
/* ... */
}
}
การตรวจหาการรองรับ At-rule เมื่อ @supports at-rule() ไม่เหมาะสม
เมื่อไม่สามารถใช้ at-rule() ได้ ไม่ว่าจะเนื่องจากการรองรับของเบราว์เซอร์หรือเพราะจำเป็นต้องมีการตรวจจับที่ละเอียดยิ่งขึ้น คุณสามารถใช้คำแนะนำด้านล่างได้
ลองใช้พร็อพเพอร์ตี้ ค่า หรือตัวเลือกก่อน
@supports สามารถตรวจหาพร็อพเพอร์ตี้ ค่า และตัวเลือกได้อยู่แล้ว (ผ่าน @supports selector(...))
ในหลายกรณี คุณสามารถใช้สิ่งเหล่านี้เพื่อตรวจหาการรองรับฟีเจอร์โดยไม่ต้องตรวจสอบ At-Rule เอง
เช่น คุณสามารถใช้ @supports (color: --foo()) แทน @supports at-rule(@function) เพื่อตรวจหาการรองรับฟังก์ชันที่กำหนดเอง
ในกรณีอื่นๆ อาจมีคลาสเทียมหรือองค์ประกอบเทียมที่ใช้ได้เฉพาะเมื่อรองรับ At-rule บางรายการ ซึ่งสามารถใช้เพื่อตรวจหาการรองรับได้
การตรวจหาประเภทการค้นหาคอนเทนเนอร์
at-rule() อนุญาตให้ตรวจหา At-rule ตามชื่อเท่านั้น
แต่จะไม่อนุญาตให้ตรวจจับไวยากรณ์หรือข้อบ่งชี้อื่นๆ
ตัวอย่างเช่น ตัวอย่างต่อไปนี้จะใช้ไม่ได้
@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) เพื่อตรวจหาการรองรับการค้นหาสไตล์ เนื่องจากจะไม่ได้ผล
แต่คุณสามารถลองใช้การค้นหาสไตล์ที่เป็นจริงเสมอแทนได้ ดังนี้
@container style(--a: 1) or (not (style(--a: 1))) {
/* Rules here will only be applied if style queries are supported */
}
ซึ่งจะจับคู่ในเบราว์เซอร์ที่รองรับการค้นหาสไตล์ ไม่ว่าคุณจะใช้ชื่อหรือค่าพร็อพเพอร์ตี้ใดก็ตาม โดยต้องเป็นชื่อหรือค่าเดียวกันในทั้ง 2 รายการ
คุณสมบัติที่กำหนดเองที่ลงทะเบียนไว้ (@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);
}
หมายเหตุ:
- ทั้ง 2 วิธีนี้จะใช้ได้ก็ต่อเมื่อช่องว่างเป็นทางเลือกที่ยอมรับได้ ในกรณีอื่นๆ คุณจะต้องใช้ JS ตามที่อธิบายไว้ด้านล่าง
- โซลูชันอเนกประสงค์จะขึ้นอยู่กับการไม่รับค่า ดังนั้นจึงใช้ไม่ได้กับการประกาศในองค์ประกอบรูท
การใช้ JavaScript เป็นทางเลือกสุดท้าย
สำหรับ At-rule ทั้งหมด ให้ตรวจสอบว่ามีอินเทอร์เฟซบางอย่างใน JavaScript หรือไม่
เช่น หากมีการกำหนด globalThis.CSSFunctionRule ระบบจะรองรับ @function
หากต้องการทดสอบอย่างละเอียดมากขึ้น (เช่น สำหรับ Prelude, กฎที่ซ้อนกัน, ตัวบ่งชี้บางอย่าง) คุณสามารถตั้งค่าการทดสอบและตรวจสอบวิธีแยกวิเคราะห์ได้ดังนี้
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()) เท่านั้นเพื่อตรวจหา At-rule ที่มีการรองรับแคบกว่าฟีเจอร์ @supports (at-rule()) เอง
หากต้องการใช้ CSS แบบมีเงื่อนไขตามการรองรับ At-Rule ที่จัดส่งก่อนฟีเจอร์นี้ ให้ใช้คำแนะนำในส่วนด้านบน
หากต้องการตรวจหาการรองรับฟีเจอร์ @supports at-rule() โดยตรง คุณสามารถใช้ At-rule ที่รับประกันว่ามีอยู่ในเบราว์เซอร์ทั้งหมดที่รองรับ @supports at-rule() เช่น @supports at-rule(@media) { ... }