Skip to content

Instantly share code, notes, and snippets.

@nexpr
Last active October 29, 2023 07:05
Show Gist options
  • Save nexpr/8cac4e49062d1414932aac2896ecd90e to your computer and use it in GitHub Desktop.
Save nexpr/8cac4e49062d1414932aac2896ecd90e to your computer and use it in GitHub Desktop.
ShadowDOM を使う CustomElement にグローバルスタイルを適用する

ShadowDOM を使う CustomElement にグローバルスタイルを適用する

CustomElement のインスタンス作成時に document.adoptedStyleSheets からグローバルスタイルを取り出して ShadowDOM の adoptedStyleSheets に追加する

注意点: document.adoptedStyleSheets の変更を検知できないので インスタンス作成後に変更できない

foo-bar {
display: block;
margin: 10px;
}
/* not applied */
.box {
color: red;
}
<!DOCTYPE html>
<script type="module">
import document_only_sheet from "./document-only-style.css" assert { type: "css" }
import global_style from "./global-style.css" assert { type: "css" }
import { globalStyle } from "./global-style.js"
global_style.global_style = true
document.adoptedStyleSheets.push(document_only_sheet, global_style)
const selector = (sheets) => {
return sheets.filter(x => x.global_style)
}
customElements.define("foo-bar", class extends globalStyle(HTMLElement, selector) {
constructor() {
super()
this.shadowRoot.innerHTML = `
<div class="box">
text
</div>
`
}
})
</script>
<foo-bar></foo-bar>
.box {
border: 3px solid green;
padding: 10px;
}
export const globalStyle = (Base, selector) => {
return class extends Base {
constructor() {
super()
const sheets = selector([...this.ownerDocument.adoptedStyleSheets])
const root = this.attachShadow({ mode: "open" })
root.adoptedStyleSheets.push(...sheets)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment