구성 가능한 스타일시트

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

생성 가능한 스타일시트를 사용하면 섀도우 DOM을 사용할 때 재사용 가능한 스타일을 만들고 배포할 수 있습니다.

브라우저 지원

  • 73
  • 79
  • 101
  • 16.4

소스

예전에는 JavaScript를 사용하여 스타일시트를 만들 수 있었습니다. 그러나 이전에는 document.createElement('style')를 사용하여 <style> 요소를 만든 다음 시트 속성에 액세스하여 기본 CSSStyleSheet 인스턴스에 대한 참조를 얻었습니다. 이 방법은 중복 CSS 코드와 그에 수반되는 팽창을 발생시킬 수 있으며, 첨부하는 작업으로 인해 팽창 여부와 관계없이 스타일이 지정되지 않은 콘텐츠가 플래시됩니다. CSSStyleSheet 인터페이스는 CSSOM이라고 하는 CSS 표현 인터페이스 컬렉션의 루트로, 프로그래매틱 방식으로 스타일시트를 조작하고 이전 메서드와 관련된 문제를 제거합니다.

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

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

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

스타일시트 구성

이를 위해 새 API를 도입하는 대신 구성 가능한 스타일시트 사양을 통해 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..."

구성된 스타일시트 사용

구성 가능한 스타일 시트에 도입된 두 번째 새로운 기능은 섀도우 루트문서에서 사용할 수 있는 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);

요약 정리

이제 웹 개발자는 생성 가능 StyleSheets를 사용하여 CSS StyleSheets를 만들고 DOM 트리에 적용할 수 있는 명시적인 솔루션을 사용할 수 있습니다. 브라우저의 기본 제공 파서와 로드 시맨틱스를 사용하는 CSS 소스 문자열에서 StyleSheets를 로드하기 위한 새로운 프라미스 기반 API가 있습니다. 마지막으로, 모든 스타일 시트 사용에 스타일 시트 업데이트를 적용하여 테마 변경, 색상 환경설정 등을 단순화하는 메커니즘이 있습니다.

데모 보기

향후 계획

구성 가능한 스타일시트의 초기 버전은 여기에 설명된 API와 함께 제공되었지만, 더욱 쉽게 사용할 수 있도록 하기 위해 진행 중입니다. 스타일시트를 삽입 및 삭제하는 전용 메서드를 사용하여 adoptedStyleSheets FrozenArray를 확장하는 제안이 있습니다. 이렇게 하면 배열 복제의 필요성이 사라지고 잠재적인 중복 스타일시트 참조를 피할 수 있습니다.

추가 정보