スタイリング
スコープ付きスタイルを安全に実現する方法は2つあります。
- スタイルオブジェクトを使う方法
- Shadow DOMとconstructableスタイルシートを使う方法
パフォーマンスの面でブラウザがより支援しやすくなるため、2番目の方法を強く推奨します。
スタイルオブジェクトを使う
Section titled “スタイルオブジェクトを使う”タグ付きテンプレート用の組み込み html 関数を使うとき、Partial<CSSStyleDeclaration> 型のスタイルオブジェクトを任意の要素の style 属性に渡すことができます。これにより、計算されたスタイルや条件付きスタイルが可能になります。スタイルオブジェクトについて詳しくはMDNを参照してください。
今すぐこのCodePenの例 ↗で試すか、実際に動く様子はこちら: スタイルオブジェクトデモ ↗
import { WebComponent } from 'https://esm.sh/web-component-base@latest'
class StyledElement extends WebComponent { static props = { emphasize: false, type: 'warn', }
#typeStyles = { warn: { backgroundColor: 'yellow', border: '1px solid orange', }, error: { backgroundColor: 'orange', border: '1px solid red', }, }
get template() { return html` <div style=${{ ...this.#typeStyles[this.props.type], padding: '1em', }} > <p style=${{ fontStyle: this.props.emphasize && 'italic' }}>Wow!</p> </div> ` }}
customElements.define('styled-elements', StyledElement)Shadow DOMとConstructableスタイルシートを使う
Section titled “Shadow DOMとConstructableスタイルシートを使う”Shadow DOMを使う場合、static styles プロパティを追加できます。これは shadowRoot のadoptedStylesheetsに追加されます。文字列、CSSStyleSheet、またはそのいずれかの配列を受け付けます。
今すぐこのCodePenの例 ↗で試すか、実際に動く様子はこちら: Constructableスタイルデモ ↗
class StyledElement extends WebComponent { static shadowRootInit = { mode: 'open', }
static styles = ` div { background-color: yellow; border: 1px solid black; padding: 1em;
p { text-decoration: underline; } } `
get template() { return html` <div> <p>Wow!?</p> </div> ` }}
customElements.define('styled-elements', StyledElement)複数のスタイルシートを合成する
Section titled “複数のスタイルシートを合成する”複数のシートを採用するには配列を渡します。これらは順番どおりに適用されるため、同じ詳細度であれば後の項目が優先されます。共有のトークンやベースシートを先に置き、コンポーネントごとのスタイルをその後に置いてください。
// tokens.js: すべてのコンポーネントで共有export const tokens = ` :host { --cozy-radius: 6px; --cozy-accent: rebeccapurple; }`
// cozy-button.jsimport { tokens } from './tokens.js'
class CozyButton extends WebComponent { static shadowRootInit = { mode: 'open' } static styles = [ tokens, ` button { border-radius: var(--cozy-radius); background: var(--cozy-accent); } `, ]}各項目は文字列でも、あらかじめ作成されたCSSStyleSheetオブジェクトでもよく、両者を混在させることもできます。CSSStyleSheet は再作成されるのではなく、そのまま採用されるため、共有インスタンスを一度だけ構築し、それを採用するすべてのコンポーネントで再利用できます。
const base = new CSSStyleSheet()base.replaceSync(tokens)
class CozyBadge extends WebComponent { static shadowRootInit = { mode: 'open' } static styles = [base, `span { font-size: 0.8em; }`]}単一の文字列は、これまでどおりそのまま機能します。配列形式は追加的なものです。