liveBook · Manning

CSS encapsulation

As explained in Web Components in Action

A styling isolation technique that prevents styles defined outside a component from unintentionally affecting its internal elements.

CSS encapsulation prevents page-level selectors from accidentally styling a component’s internal elements. The Shadow DOM provides this boundary, making it especially useful as web interfaces become more complex and global styles become harder to control. section 8.3 section 9.0

Use the Shadow DOM with these distinctions in mind:

  • Style elements inside the shadow root with ordinary selectors such as span; outside selectors cannot latch onto those internal classes or elements. section 9.2
  • Style the component boundary with :host. A selector such as sample-component targets the shadow host, not the contents of the shadow root. section 9.2
  • Account for inherited styles: rules applied to an ancestor, such as body, can still affect descendants inside the shadow tree even when selectors cannot cross into it. section 9.2

Protecting a stepper component

Attach an open shadow root, place the stepper’s buttons, counter, and style element inside it, and use :host for layout. Page-level button, span, or class selectors then cannot directly restyle those internal elements, while inherited ancestor properties may still require an explicit reset. section 9.2

Listing 9.3. Using the Shadow DOM to protect our stepper component’s style
class SampleComponent extends HTMLElement {
   connectedCallback() {
       const root =                                             #1
           this.attachShadow({mode: 'open'});
       root.innerHTML = `<button class="big-button">-</button>
                         <span class="increment-number">5</span>
                         <button class="big-button">+</button>
           <style>
                sample-component {
                   display: flex;
                }

                span {                                          #2
                   font-size: 24px;
                   background-color: #770311;
                   color: white;
                   font-family: Helvetica;
                   display: inline-block;
                   padding: 11px;
                   border: none;
                }
                button {
                   border-radius: 0 50px 50px 0;
                   border: none;
                   width: 50px;
                   height: 50px;
                   font-size: 36px;
                   font-weight: bold;
                   background: none;
                   background-color: red;
                   color: white;
               }

               button:first-child {
                   border-radius: 50px 0 0 50px;
               }

               button:active {
                   background-color: #960000;
               }

               button:focus {
                   outline: thin dotted;
               }

           </style>`;
   }
}

Inspect the complete stepper example, including attachShadow, internal markup, and component-local CSS. section 9.2

How Web Components in Action covers it

How deep it goes
Explains selector boundaries, :host, inheritance, and resets, while deferring difficult CSS polyfill implementation details.
Examples
Demonstrates a protected stepper, inherited body text styles, :host layout, and an all: initial reset.
What it assumes
Assumes familiarity with HTML, CSS selectors, and Web Components while introducing Shadow DOM CSS behavior incrementally.
What you can do after
Build Web Components with Shadow DOM boundaries, local selectors, :host rules, and explicit handling for inherited styles.
How it connects
Connects CSS selectors and inheritance with the Shadow DOM, Web Components, shadow hosts, and CSS polyfills.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Web Components in Action. The section links point to the parts of the book it draws on.