Day 10: global styles and web components
posted on
It’s time to get me up to speed with modern CSS. There’s so much new in CSS that I know too little about. To change that I’ve started #100DaysOfMoreOrLessModernCSS. Why more or less modern CSS? Because some topics will be about cutting-edge features, while other stuff has been around for quite a while already, but I just have little to no experience with it.
I was wondering what happens with HTML elements in web components when I add styles to the document. Under which circumstances do global styles defined in a style element or external stylesheet apply to these elements?
As it turns out, it depends on how you create and use the components. In my test setup I have an HTML document, a stylesheet and three different components.
styles.css
div {
border: 2px solid red;
}
index.html
<head>
…
<link rel="stylesheet" href="styles.css">
</head>
<body>
<basic-component></basic-component>
<shadow-component></shadow-component>
<slot-component>
<div>Bye World!</div>
</slot-component>
<script src="basic-component.js" type="module"></script>
<script src="shadow-component.js" type="module"></script>
<script src="slot-component.js" type="module"></script>
</body>
Web component without shadow DOM
If you add an element to a web component using JavaScript and you don’t attach it to the shadow DOM, styles defined outside the web component apply.
basic-component.js
class BasicComponent extends HTMLElement {
constructor() {
super();
this.innerHTML = `<div>Hello World!</div>`
}
}
customElements.define('basic-component', BasicComponent);
Web component with shadow DOM
If you attach an element to the shadow DOM inside the web component, style declarations from the outside don’t apply.
shadow-component.js
class ShadowComponent extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
this.shadowRoot.innerHTML = `<div>Hello World!</div>`
}
}
customElements.define('shadow-component', ShadowComponent);
Web Component with slotted content
If you attach an element to the shadow DOM inside the web component and you pass slotted content, style declarations from the outside only apply to the slotted content.
class SlotComponent extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
this.shadowRoot.innerHTML = `
<div>Hello World!</div>
<slot></slot>
`
}
}
customElements.define('slot-component', SlotComponent);
PS: The next post is coming on Monday because weekends are for family and friends. ❤️
Further reading
- Day 18: inheritable styles and web components
- Day 28: custom properties and web components
- Day 45: the specificity of ::slotted() content
- Day 60: the ::part() pseudo-element
Overview: 100 Days Of More Or Less Modern CSS