Skip to content

Latest commit

 

History

History
92 lines (73 loc) · 3.06 KB

File metadata and controls

92 lines (73 loc) · 3.06 KB
chapter 8
subtitle Bringing CSS into ShadowDOM
hidden false

Components with ShadowDOM typically want to introduce some CSS into their ShadowRoots. This is done with the use of adoptedStyleSheets. Catalyst provides a @style decorator to more easily add CSS to your component.

If your CSS lives in a different file, you can import the file with using the assert { type: 'css' } import assertion. You might need to configure your bundler tool to allow for this. If you're unfamiliar with this feature, you can check out the web.dev article on CSS Module Scripts:

import {controller, style} from '@github/catalyst'
import DesignSystemCSS from './my-design-system.css' assert { type: 'css' }

@controller
class UserRow extends HTMLElement {
  @style designSystem = DesignSystemCSS

  connectedCallback() {
    this.attachShadow({ mode: 'open' })
    // adoptedStyleSheets now includes our DesignSystemCSS!
    console.assert(this.shadowRoot.adoptedStyleSheets.includes(this.designSystem))
  }
}

Multiple @style tags are allowed, each one will be applied to the adoptedStyleSheets meaning you can split your CSS without worry!

import {controller} from '@github/catalyst'
import UtilityCSS from './my-design-system/utilities.css' assert { type: 'css' }
import NormalizeCSS from './my-design-system/normalize.css' assert { type: 'css' }
import UserRowCSS from './my-design-system/components/user-row.css' assert { type: 'css' }

@controller
class UserRow extends HTMLElement {
  @style utilityCSS = UtilityCSS
  @style normalizeCSS = NormalizeCSS
  @style userRowCSS = UserRowCSS

  connectedCallback() {
    this.attachShadow({ mode: 'open' })
    // adoptedStyleSheets now includes our 3 stylesheets!
    console.assert(this.shadowRoot.adoptedStyleSheets.length === 3)
  }
}

Defining CSS in JS

The @style decorator takes a constructed CSSStyleSheet object. These must be constructed in JavaScript, but can be generated by helper libraries or custom loaders. If, for example, you like writing your CSS the same file as your element, you can manually create a CSSStyleSheet:

import {controller, style} from '@github/catalyst'

const sheet = new CSSStyleSheet()
sheet.replaceSync(`
  :host {
    display: flex
  }
`)

@controller
class UserRow extends HTMLElement {
  @style componentCSS = sheet

  connectedCallback() {
    this.attachShadow({ mode: 'open' })
  }
}

Alternatively you can import one, as long as the return value is a Constructable CSSStyleSheet:

import {controller, style} from '@github/catalyst'
import {css} from '@acme/cool-css'

@controller
class UserRow extends HTMLElement {
  @style componentCSS = css`
    :host {
      display: flex
    }
  `

  connectedCallback() {
    this.attachShadow({ mode: 'open' })
    console.assert(this.componentCSS instanceof CSSStyleSheet)
  }
}