CSS ::slotted() Pseudo-Element in Web Components
The ::slotted() CSS pseudo-element is used within a Web
Component's Shadow DOM to select and style elements that are projected
into a <slot>. This article covers the fundamental
purpose of ::slotted(), how to write its syntax, how
specificity works between the component and the light DOM, and the key
limitations developers encounter when styling slotted content.
The Purpose of ::slotted()
When building Web Components using Shadow DOM, styles defined inside
the shadow root are scoped exclusively to that component. However,
components frequently include <slot> elements, which
accept markup passed from the outside page (the "light DOM").
Because slotted elements technically remain in the light DOM,
standard shadow DOM selectors cannot reach them. The
::slotted() pseudo-element bridges this boundary, allowing
the component author to define default or contextual styles for incoming
slotted elements from within the component's internal stylesheet.
Syntax and Basic Usage
The ::slotted() pseudo-element must take a selector
argument specifying which elements within the slot to target.
/* Style any <p> element placed in a slot */
::slotted(p) {
color: #333333;
margin-bottom: 1rem;
}
/* Style only elements with a specific class inside a slot */
::slotted(.highlight) {
background-color: yellow;
}
/* Target elements within a specific named slot */
slot[name="header"]::slotted(h1) {
font-size: 1.5rem;
}If you want to style all elements placed inside a slot, use the universal selector:
::slotted(*) {
box-sizing: border-box;
}Key Rules and Limitations
While ::slotted() provides access to external nodes, it
operates under strict constraints designed to preserve DOM
encapsulation.
1. Only Direct Children Can Be Targeted
The selector passed to ::slotted() only matches
top-level nodes directly passed into the slot. It cannot target nested
descendants of slotted elements.
- Works:
::slotted(div)selects<div slot="content"> - Fails:
::slotted(div span)or::slotted(span)will not match a<span>located inside that<div>.
2. Simple Selectors Only
The argument inside ::slotted() must be a simple
selector or compound selector representing the slotted node itself. You
cannot use complex combinators (like descendant or child
> selectors) inside the parentheses.
3. Light DOM Styles Take Precedence
CSS specificity works differently across the shadow boundary. Any
styles applied to the slotted elements from the host document (the light
DOM) will override the ::slotted() styles defined inside
the Shadow DOM, regardless of the shadow selector's specificity. The
Shadow DOM styles act primarily as fallback or default styling for the
projected content. To override light DOM styles from inside the
component, !important must be added to the property
rule.