구성 가능한 스타일시트

원활하게 재사용 가능한 스타일.

구성 가능한 스타일시트Shadow DOM을 사용할 때 재사용 가능한 스타일을 만들고 배포하는 방법입니다.

브라우저 지원

  • 73
  • 79
  • 101
  • 16.4

소스

JavaScript를 사용하여 스타일시트를 만드는 것은 언제나 가능했습니다. 하지만 이전에는 document.createElement('style')를 사용하여 <style> 요소를 만들고 시트 속성에 액세스하여 기본 CSSStyleSheet 인스턴스에 관한 참조를 가져오는 프로세스가 사용되었습니다. 이 메서드를 사용하면 중복된 CSS 코드와 그에 따른 팽창이 발생할 수 있으며, 이 코드를 첨부하면 팽창 여부와 상관없이 스타일이 지정되지 않은 콘텐츠가 깜박입니다. CSSStyleSheet 인터페이스는 CSSOM이라고 하는 CSS 표현 인터페이스 모음의 루트로, 프로그래매틱 방식으로 스타일시트를 조작하고 이전 메서드와 관련된 문제를 제거합니다.

CSS의 준비 및 적용을 보여주는 다이어그램

구성 가능한 스타일시트를 사용하면 공유된 CSS 스타일을 정의하고 준비한 다음 이러한 스타일을 여러 그림자 루트 또는 문서에 중복 없이 쉽게 적용할 수 있습니다. 공유된 CSSStyleSheet의 업데이트는 이 스타일 시트가 채택된 모든 루트에 적용되며, 시트가 로드되면 스타일시트 채택이 빠르고 동기식이 됩니다.

구성 가능한 스타일시트에서 설정한 연결은 다양한 애플리케이션에 적합합니다. 여러 구성요소에 사용되는 중앙 집중식 테마를 제공하는 데 사용할 수 있습니다. 테마는 구성요소에 전달되는 CSSStyleSheet 인스턴스일 수 있으며 테마 업데이트는 구성요소로 자동으로 전파됩니다. 이 API는 캐스케이드에 의존하지 않고 CSS 커스텀 속성 값을 특정 DOM 하위 트리에 배포하는 데 사용할 수 있습니다. 브라우저의 CSS 파서에 대한 직접 인터페이스로 사용할 수도 있으므로 DOM에 스타일시트를 삽입하지 않고도 쉽게 스타일시트를 미리 로드할 수 있습니다.

스타일시트 구성

이를 위해 새 API를 도입하는 대신 구성 가능한 StyleSheets 사양을 사용하면 CSSStyleSheet() 생성자를 호출하여 스타일시트를 명령형으로 만들 수 있습니다. 결과로 반환되는 CSSStyleSheet 객체에는 스타일이 지정되지 않은 콘텐츠 플래시 (FOUC)를 트리거하지 않고도 스타일시트 규칙을 더 안전하게 추가하고 업데이트할 수 있는 두 가지 새로운 메서드가 있습니다. replace()replaceSync() 메서드는 모두 스타일시트를 CSS 문자열로 대체하고 replace()는 프로미스를 반환합니다. 두 경우 모두 외부 스타일시트 참조가 지원되지 않습니다. @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..."

구성된 스타일시트 사용

구성 가능한 StyleSheets에서 도입한 두 번째 새로운 기능은 섀도 루트문서에서 사용할 수 있는 adoptedStyleSheets 속성입니다. 이렇게 하면 CSSStyleSheet에서 정의한 스타일을 지정된 DOM 하위 트리에 명시적으로 적용할 수 있습니다. 이렇게 하려면 해당 요소에 적용할 하나 이상의 스타일시트의 배열로 속성을 설정합니다.

// 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