What Is ::slotted()?
The ::slotted() CSS pseudo-element represents any element that has been placed into a slot inside an HTML template. This powerful selector is essential for styling composed web components, allowing developers to style slotted content from within the shadow DOM while maintaining proper encapsulation boundaries.
When building reusable web components, the slot mechanism enables composition--child elements defined outside the component can be projected into specific positions within the component's shadow tree. The ::slotted() pseudo-element provides the bridge to style these composed elements from within the component's encapsulated context.
The slot system is a cornerstone of modern web component architecture, enabling flexible component composition while preserving style boundaries between light DOM and shadow DOM contexts.
MDN Web Docs provides the authoritative specification for this pseudo-element and its role in the CSS Scoping Module.
Understanding Slots in Web Components
Slots are placeholders inside a web component's shadow DOM that accept content from the light DOM. This composition model allows developers to create flexible, reusable components that can accept different content while maintaining consistent styling and structure.
The slot mechanism operates on a simple but powerful principle: elements in the light DOM with a slot attribute matching a slot's name are projected into that slot position within the shadow tree. This separation of concerns enables component authors to focus on structure and styling while giving component consumers freedom over content.
Default Slot
The default slot serves as a catch-all for any content that doesn't specify a named slot. When multiple elements without slot attributes are provided as children, they all render in the default slot position. This pattern is commonly used for main content areas, body text, or any flexible content projection.
<template>
<div class="card-body">
<slot></slot> <!-- Default slot -->
</div>
</template>
Named Slots
Named slots enable precise content placement within a component. Each named slot accepts only elements with a matching slot attribute value. This pattern supports complex component designs with multiple content areas such as headers, footers, sidebars, and main content sections.
<template>
<header>
<slot name="header"></slot>
</header>
<main>
<slot name="content"></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</template>
Web.dev offers Google's comprehensive guide on slot composition patterns for modern web applications.
The ::slotted() Pseudo-Element
The ::slotted() pseudo-element allows styling of elements that have been placed into a slot from within the component's shadow DOM CSS. This is crucial because slotted elements technically exist in the light DOM--yet ::slotted() provides a mechanism to style them from within the encapsulated context.
This cross-boundary styling capability solves a common challenge: how can a component apply base styles to slotted content without affecting other elements on the page? The answer lies in the unique positioning of ::slotted()--it bridges the shadow DOM boundary while respecting encapsulation.
Syntax
/* Selects any element placed inside a slot */
::slotted(*) {
font-weight: bold;
}
/* Selects any span placed inside a slot */
::slotted(span) {
color: #0066cc;
}
/* Selects elements matching a class within a slot */
::slotted(.highlight) {
background-color: yellow;
}
/* Selects specific element types with classes */
::slotted(div.content) {
padding: 1rem;
}
The MDN Web Docs provide complete syntax documentation and browser compatibility details for this selector.
1<template id="card-template">2 <style>3 .card {4 border: 1px solid #e0e0e0;5 border-radius: 8px;6 overflow: hidden;7 font-family: system-ui, sans-serif;8 }9 10 .card-header {11 background-color: #f5f5f5;12 padding: 1rem;13 border-bottom: 1px solid #e0e0e0;14 }15 16 .card-body {17 padding: 1rem;18 }19 20 /* Style slotted elements */21 ::slotted(h2) {22 margin: 0;23 font-size: 1.25rem;24 color: #333;25 }26 27 ::slotted(.content) {28 color: #555;29 line-height: 1.6;30 }31 32 ::slotted(.actions button) {33 background-color: #0066cc;34 color: white;35 border: none;36 padding: 0.5rem 1rem;37 border-radius: 4px;38 }39 </style>40 41 <div class="card">42 <div class="card-header">43 <slot name="header"><h2>Default Header</h2></slot>44 </div>45 <div class="card-body">46 <slot name="content"><p>Default content goes here</p></slot>47 </div>48 <div class="card-footer">49 <slot name="footer">50 <div class="actions"><button>Default Action</button></div>51 </slot>52 </div>53 </div>54</template>Limitations and Considerations
Cannot Style Children of Slotted Elements
The ::slotted() selector can only target the top-level element placed into a slot. It cannot traverse into the children of that element. This limitation exists because ::slotted() represents the element as it was placed into the slot, not as a virtual element within the shadow tree.
/* This works - targeting the slotted element directly */
::slotted(div.content) {
color: blue;
}
/* This does NOT work - cannot target children */
::slotted(div.content) span {
color: red;
}
/* Alternative approach - use CSS custom properties */
::slotted(div.content) {
--nested-color: blue;
}
::slotted(div.content) span {
color: var(--nested-color);
}
Cannot Style Text Nodes
Text nodes placed directly into a slot without an element wrapper cannot be targeted with ::slotted(). The pseudo-element only matches element nodes, not text content.
Limited Pseudo-Element Support
Certain tree-abiding pseudo-elements can follow ::slotted():
::slotted(*)::before {
content: "→ ";
}
::slotted(button)::after {
content: " ↵";
}
CSS-Tricks documents practical web component styling patterns including these limitations.
| Aspect | ::slotted() | ::part() |
|---|---|---|
| Target | Light DOM elements projected into slots | Shadow DOM elements explicitly exposed |
| Direction | From shadow DOM to light DOM | From light DOM to shadow DOM |
| Purpose | Component styles slotted content | External consumers style internals |
| Visibility | Automatic - all slotted content | Manual - requires part attribute |
| Use Case | Base styling of composed content | Theming and customization |
Best Practices
Use for Base Styling Only
Reserve ::slotted() for applying foundational styles--typography, spacing, colors that establish a consistent look. For comprehensive theming or customization needs, combine ::slotted() with CSS custom properties:
::slotted(.content) {
font-family: var(--card-font-family, system-ui);
font-size: var(--card-font-size, 1rem);
color: var(--card-text-color, #333);
line-height: var(--card-line-height, 1.6);
}
This approach gives consumers control through CSS custom properties while maintaining consistent defaults across your component library. By combining these techniques, you create a flexible system that supports both component encapsulation and end-user customization without compromising either goal.
For teams building enterprise-scale applications, following web development best practices ensures maintainable, scalable component architectures.
Combine with Slot Names
When components have multiple named slots, use ::slotted() with the slot attribute selector to style content appropriately for each position:
::slotted([slot="header"]) {
font-size: 1.25rem;
font-weight: 600;
}
::slotted([slot="footer"]) {
font-size: 0.875rem;
color: #666;
}
Provide Fallback Content
Always provide meaningful fallback content within <slot> elements. This ensures components render correctly even when consumers don't provide slotted content, improving the resilience of your component library.
Browser Support
100%
Baseline Support
53
Chrome+ (Aug 2016)
59
Firefox+ (Mar 2018)
10.1
Safari+ (Mar 2017)
Article & Content Cards
Cards frequently use slots for title, body, image, and action areas. ::slotted() provides consistent styling for composed elements while maintaining encapsulation.
Form Components
Form components like input groups, select wrappers, and form sections use slots to accept labels, inputs, and help text with styled integration.
Navigation Components
Navigation headers and sidebars use slots to accept menu items and child components with proper styling hooks.
Layout Components
Grid and layout components use slots to accept content sections with appropriate spacing and typography across all breakpoints.
Frequently Asked Questions
Sources
- MDN Web Docs - ::slotted() - Official documentation for the ::slotted() pseudo-element
- CSS-Tricks - Web Component Pseudo-Classes and Pseudo-Elements - Practical web component styling patterns
- Web.dev - Template, slot, and shadow - Google's guide on slot composition
- CSS Scoping Module Level 1 - W3C specification for slotted pseudo-element
- Southleft - Demystifying Web Components: Understanding Slots - Advanced styling techniques