tezvyn:

Shadow DOM encapsulation vs CSS Modules

AI-drafted, machine-checkedSource: interviewadvanced
WHAT IT TESTS

Understanding real browser encapsulation versus build-time name scoping.

OUTLINE

Shadow DOM creates a separate tree blocking selectors both ways, CSS Modules only rename classes, and global styles need explicit bridges.

WHAT THIS TESTS The interviewer checks whether you understand the difference between a real DOM and CSS boundary enforced by the browser and a convention that only rewrites names at build time, plus the practical cost of true encapsulation.

A GOOD ANSWER COVERS Shadow DOM attaches a shadow root to a host element, creating a separate subtree. Styles defined inside that root cannot leak out, and selectors written outside cannot reach in. The boundary is enforced at runtime by the browser. A few things still cross it deliberately: inherited CSS properties such as color and font, CSS custom properties, and explicit hooks like the ::part pseudo-element and ::slotted for projected content. By contrast, CSS Modules is a build step that hashes class names to make them unique, so collisions are avoided, but there is no real boundary; global stylesheets, resets, and descendant selectors still apply because the elements live in the normal light DOM.

COMMON WRONG ANSWERS Claiming CSS Modules gives the same isolation as Shadow DOM is wrong; it only prevents name clashes. Forgetting that Shadow DOM blocks your own global design tokens is a common trap. Assuming a global reset or utility framework will style shadow content also fails.

LIKELY FOLLOW-UPS How do design tokens reach into shadow trees? Via custom properties, which pierce the boundary. How do you let consumers theme parts? Expose ::part. How do slots interact with styling? How does form participation work for custom elements?

ONE CONCRETE EXAMPLE A web component date picker uses Shadow DOM, so the app Tailwind utilities and global reset have no effect inside it, which keeps it consistent everywhere but means you cannot restyle its internals with normal classes. To theme it you define custom properties like a primary color variable that the component reads, and you expose ::part(button) so consumers can adjust the trigger without breaking encapsulation.

Read the original → developer.mozilla.org

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.