สไตล์ชีตที่สร้างได้

มีสไตล์ที่นำกลับมาใช้ใหม่ได้

สไตล์ชีตที่สร้างได้คือวิธีสร้างและกระจายรูปแบบที่นำมาใช้ใหม่ได้เมื่อใช้ Shadow DOM

การรองรับเบราว์เซอร์

  • 73
  • 79
  • 101
  • 16.4

แหล่งที่มา

การสร้างสไตล์ชีตโดยใช้ JavaScript สามารถทำได้เสมอ อย่างไรก็ตาม ที่ผ่านมากระบวนการสร้างเอลิเมนต์ <style> โดยใช้ document.createElement('style') จากนั้นเข้าถึงพร็อพเพอร์ตี้ชีตเพื่อรับการอ้างอิงไปยังอินสแตนซ์ CSSStyleSheet พื้นฐาน วิธีนี้สามารถสร้างโค้ด CSS ที่ซ้ำกันและการขยายตัวของแอสเซทของโค้ดได้ และการแนบทำให้เกิดเนื้อหาที่ไม่มีการจัดรูปแบบอย่างรวดเร็ว ไม่ว่าเนื้อหาจะมีขนาดเกินหรือไม่ อินเทอร์เฟซ CSSStyleSheet เป็นคอลเล็กชันหลักของอินเทอร์เฟซตัวแทน CSS ที่เรียกว่า CSSOM ซึ่งนำเสนอวิธีแบบเป็นโปรแกรมในการจัดการสไตล์ชีตและขจัดปัญหาที่เชื่อมโยงกับเมธอดเดิม

แผนภาพแสดงการเตรียมและการใช้บริการ CSS

สไตล์ชีตที่สร้างได้จะช่วยให้สามารถกำหนดและจัดเตรียมสไตล์ CSS ที่แชร์ จากนั้นจึงนำรูปแบบเหล่านั้นไปใช้กับ Shadow Roots หรือเอกสารได้อย่างง่ายดายและไม่ทำซ้ำ การอัปเดต CSSStyleSheet ที่แชร์จะมีผลกับรูททั้งหมดที่เคยนำไปใช้ และการใช้สไตล์ชีตจะทำงานพร้อมกันอย่างรวดเร็วเมื่อโหลดชีตแล้ว

การเชื่อมโยงที่ตั้งค่าโดยสไตล์ชีตที่สามารถสร้างได้จะให้ประโยชน์แก่แอปพลิเคชันต่างๆ มากมาย ธีมดังกล่าวสามารถใช้เพื่อจัดเตรียมธีมส่วนกลางที่คอมโพเนนต์จำนวนมากใช้ โดยธีมอาจเป็นอินสแตนซ์ CSSStyleSheet ที่ส่งไปยังคอมโพเนนต์ จากนั้นการอัปเดตธีมจะเผยแพร่ไปยังคอมโพเนนต์โดยอัตโนมัติ ซึ่งใช้เพื่อกระจายค่าพร็อพเพอร์ตี้ที่กำหนดเองของ CSS ไปยังโครงสร้างย่อย DOM ที่เจาะจงได้โดยไม่ต้องพึ่งการเรียงซ้อน นอกจากนี้ยังใช้เป็นอินเทอร์เฟซโดยตรงไปยังโปรแกรมแยกวิเคราะห์ CSS ของเบราว์เซอร์ ทำให้ง่ายต่อการโหลดสไตล์ชีตล่วงหน้าโดยไม่ต้องแทรกไฟล์ลงใน DOM

การสร้างสไตล์ชีต

แทนที่จะนำ API ใหม่มาใช้เพื่อบรรลุเป้าหมายนี้ ข้อมูลจำเพาะของ Style Sheets ที่สร้างได้ช่วยให้สร้างสไตล์ชีตได้อย่างจําเป็นโดยการเรียกใช้ตัวสร้าง CSSStyleSheet() ออบเจ็กต์ CSSStyleSheet ที่ได้มี 2 วิธีการใหม่ที่ช่วยให้เพิ่มและอัปเดตกฎสไตล์ชีตได้อย่างปลอดภัยยิ่งขึ้นโดยไม่ต้องเรียกใช้ Flash of Unstyled Content (FOUC) ทั้งเมธอด replace() และ replaceSync() จะแทนที่สไตล์ชีตด้วยสตริง CSS และ replace() จะแสดงผล "Promise" ในทั้ง 2 กรณี ระบบจะไม่รองรับการอ้างอิงสไตล์ชีตภายนอก โดยระบบจะไม่สนใจกฎ @import และจะแสดงคำเตือน

const sheet = new CSSStyleSheet();

// replace all styles synchronously:
sheet.replaceSync('a { color: red; }');

// replace all styles:
sheet.replace('a { color: blue; }')
  .then(() => {
    console.log('Styles replaced');
  })
  .catch(err => {
    console.error('Failed to replace styles:', err);
  });

// Any @import rules are ignored.
// Both of these still apply the a{} style:
sheet.replaceSync('@import url("styles.css"); a { color: red; }');
sheet.replace('@import url("styles.css"); a { color: red; }');
// Console warning: "@import rules are not allowed here..."

การใช้สไตล์ชีตที่สร้างขึ้น

ฟีเจอร์ใหม่อย่างที่ 2 จาก Style Sheets ที่สร้างได้คือพร็อพเพอร์ตี้ adoptedStyleSheets ที่มีอยู่ใน Shadow Roots และ Documents วิธีนี้ช่วยให้เรานำรูปแบบที่ CSSStyleSheet กำหนดไปใช้กับซับทรี DOM ที่ระบุได้อย่างชัดเจน ในการดำเนินการดังกล่าว เราจะตั้งค่าพร็อพเพอร์ตี้เป็นอาร์เรย์ของสไตล์ชีตอย่างน้อย 1 รายการเพื่อใช้กับองค์ประกอบนั้น

// Create our shared stylesheet:
const sheet = new CSSStyleSheet();
sheet.replaceSync('a { color: red; }');

// Apply the stylesheet to a document:
document.adoptedStyleSheets.push(sheet);

// Apply the stylesheet to a Shadow Root:
const node = document.createElement('div');
const shadow = node.attachShadow({ mode: 'open' });
shadow.adoptedStyleSheets.push(sheet);

Putting it all together

With Constructable StyleSheets, web developers now have an explicit solution for creating CSS StyleSheets and applying them to DOM trees. We have a new Promise-based API for loading StyleSheets from a string of CSS source that uses the browser's built-in parser and loading semantics. Finally, we have a mechanism for applying stylesheet updates to all usages of a StyleSheet, simplifying things like theme changes and color preferences.

View Demo

Looking ahead

The initial version of Constructable Stylesheets shipped with the API described here, but there's work underway to make things easier to use. There's a proposal to extend the adoptedStyleSheets FrozenArray with dedicated methods for inserting and removing stylesheets, which would obviate the need for array cloning and avoid potential duplicate stylesheet references.

More information