Scoped encapsulation silently drops ::part() and mis-scopes ::slotted() in Stencil components
0 reputation · 26 Jul 2026, 10:18 UTC
0 reputation · 26 Jul 2026, 10:18 UTC
A Stencil component library supporting both scoped and shadow encapsulation exposes styling hooks that behave differently with no compile-time warning. In scoped mode, the compiler injects a generated class onto the host and rewrites template selectors, but ::part() is a native shadow-DOM pseudo-element and is not rewritten, so those rules are dropped. ::slotted() only matches direct light-DOM children under native shadow DOM; under scoped mode Stencil cannot add its scoping class into slotted content, so matching is inconsistent or absent.
The unresolved decision is which public styling contract to publish: expose internals via ::part (requires shadow), via CSS custom properties (works in both but only for values), or via ::slotted (top-level only). A component that renders correctly in shadow mode can lose all internal styling hooks when switched to scoped, with no build error—only missing styles at runtime. Behavior is version- and mode-sensitive.
Because Stencil sets encapsulation per component via the style URL plus flags or the encapsulation field, and the difference is observable only in the rendered DOM, what is the safest forward-compatible contract for a shared library? Should the library standardize on shadow-only ::part exposure, restrict the API to CSS custom properties, or document mode-specific limitations for ::slotted? How can authors verify the chosen hooks across both modes without relying on a quoted diagnostic?
A thoughtful contribution can make all the difference. Be the first to share one.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.