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);
Bye World!

PS: The next post is coming on Monday because weekends are for family and friends. ❤️

See on CodePen

Further reading

Do you want to learn even more awesome CSS?

I'm running a workshop with my friends at Smashing Magazine in which I introduce you to the most useful modern features in CSS and show how you can implement them today in your code base to improve scalability, maintainability, and productivity.

Learn more about the workshop!

Overview: 100 Days Of More Or Less Modern CSS