Shadow DOM

hard

The elements are right there. Your CSS selectors just can't see them.

Every widget on this page lives inside an open shadow root. Plain CSS selectors can't pierce shadow boundaries โ€” Playwright pierces them automatically, while Selenium requires walking element.shadowRoot (via getShadowRoot()) level by level.

Input inside a shadow root

The input and its live mirror both live inside the shadow root of <pg-shadow-input>. Type into it and assert the mirrored value.

Counter inside a shadow root

The button and its count are shadow DOM. The element also dispatches a composed CustomEvent that crosses the shadow boundary โ€” the light-DOM status line below proves it.

Shadow counter has not been clicked yet.

Nested shadow roots

<pg-shadow-progress> holds a progress bar in its shadow root โ€” and inside that shadow root sits another custom element, <pg-shadow-badge>, with its own shadow root. Chain through both levels to read the badge.

Slotted light DOM

The card frame is shadow DOM, but the text inside it is a light-DOM child projected through a <slot> โ€” it stays reachable with normal selectors even though it renders inside the shadow.

This text lives in the light DOM but renders inside the shadow card.