LEARNING OBJECTIVES ⌵
- Synthesize all Chapter 84 concepts into a production-grade
<media-card>Web Component. - Architect a 5-slot layout:
avatar,header,media, default body, andactions. - Implement declarative fallback states for media placeholders and action toolbars.
- Apply CSS Custom Property theme bridges and
::slotted()styling rules. - Bind WAI-ARIA accessibility landmarks and handle dynamic slot mutations via
slotchange.
🎬 INTERACTIVE VISUAL PIPELINE
Core Architecture Simulation
1. Input
Directives & Tags
2. Parse
Tokenizer & AST
3. Layout
Box Model & Flow
4. Render
GPU Paint & Composite
PHASE 1: INPUT & DIRECTIVES
Browser receives declarative markup stream, parsing tag tokens and initializing component state.
📖 The Mental Model & Story (Intuitive Foundation)
Imagine an enterprise design system engineering team at a Fortune 500 media conglomerate.
The design team needs a single, unified Media Card component used across 12 different product surfaces:
- In the Social Feed, it displays a user avatar, author name, timestamp, an uploaded photo, user captions, and Like/Share buttons.
- In the Video Streaming Portal, the avatar is omitted, the media slot receives an interactive
<video>player, and the action slot contains a "Watch Trailer" button. - In the Press Release Feed, the media slot contains a company logo, and the action slot contains a "Download PDF" link.
+-------------------------------------------------------------------------------+
| ENTERPRISE <media-card> ANATOMY |
+-------------------------------------------------------------------------------+
| |
| +-----------------------------------------------------------------------+ |
| | HEADER VIEWPORT: | |
| | [ <slot name="avatar"> ] [ <slot name="header"> (Title + Subtitle) ]| |
| +-----------------------------------------------------------------------+ |
| | MEDIA VIEWPORT: | |
| | | |
| | [ <slot name="media"> (Image, Video, or SVG Fallback) ] | |
| | | |
| +-----------------------------------------------------------------------+ |
| | BODY VIEWPORT: | |
| | [ <slot> (Default Unnamed Slot for Article / Rich Text) ] | |
| +-----------------------------------------------------------------------+ |
| | ACTIONS VIEWPORT: | |
| | [ <slot name="actions"> (Interactive Buttons / Links) ] | |
| +-----------------------------------------------------------------------+ |
| |
+-------------------------------------------------------------------------------+
Instead of writing 12 brittle variations with dozens of confusing boolean flags (hasAvatar={true}, mediaType="video", showFooter={false}), the team ships a single, highly composable <media-card> element powered natively by HTML Slots and Templates.
Technical Deep Dive & Specifications
The Enterprise Component Architecture
<media-card>
│
┌────────────────┴────────────────┐
│ │
Light DOM Nodes Shadow DOM Root
│ │
┌──────────────┼──────────────┐ ├── Static Template (<template>)
│ │ │ ├── Theme Tokens (--media-card-*)
slot="avatar" slot="header" slot="media" ├── Header Grid Layout
│ │ │ ├── Media Aspect Ratio Box (16:9)
└──────────────┼──────────────┘ ├── Body Padding Container
│ ├── Actions Flex Toolbar
Composed Flat Tree └── slotchange Event Listeners
│ (Toggles empty-slot CSS)
v
Rendered Visual Card
Slot Contract & Fallback Specifications
| Slot Name | Intended Payload | Fallback Behavior When Omitted | Accessibility / ARIA Role |
|---|---|---|---|
name="avatar" |
Circular <img>, <svg>, or avatar badge |
Renders a neutral geometric avatar placeholder. | aria-hidden="true" on decorative avatar. |
name="header" |
<h3> title and metadata spans |
Renders <h3>Untitled Broadcast</h3>. |
role="heading" aria-level="3". |
name="media" |
<img>, <video>, or <iframe> |
Renders a high-contrast blueprint SVG illustration. | Media wrapper with semantic <figure>. |
| (Default) | Paragraphs, text blocks, markdown content | Renders <p>No description provided.</p>. |
Body <section>. |
name="actions" |
<button> elements, interactive links |
Collapses the action bar container (display: none). |
Toolbar landmark role="toolbar". |
Design System Theme Tokens (CSS Custom Properties)
:host {
--card-bg: #1e293b;
--card-border: #334155;
--card-radius: 12px;
--card-accent: #38bdf8;
--card-text: #f8fafc;
--card-subtext: #94a3b8;
}
💻 Interactive Code Playground
Starter Code
Line-by-Line Code Breakdown
- Line 66–70 (
static template = (() => { ... })()): Implements static template compilation. The component's HTML blueprint is parsed only once across all instances. - Line 183 (
this.actionsSlot.addEventListener('slotchange', ...)): Tracks dynamic mutations to theactionsslot. - Line 192–198 (
syncActionsVisibility()): If the consumer does not provide any action elements, the footer wrapper is automatically hidden (display: none), maintaining clean layout margins. - Line 124–129 (
::slotted([slot="media"])): Forces any projected<img>or<video>to fill the 16:9 aspect-ratio media container perfectly.
Expected Browser Render Output
+---------------------------------------------------------------+
| (O) Sarah Connor |
| Staff Infrastructure Engineer · 2h ago |
+---------------------------------------------------------------+
| [ =================== Microchip Photo ===================== ] |
| [ ======================= (16:9) ========================== ] |
+---------------------------------------------------------------+
| Successfully migrated our core telemetry ingestion pipeline |
| to native Web Components and Web Workers... |
+---------------------------------------------------------------+
| [ 💬 Comment ] [ 🚀 Repost ] |
+---------------------------------------------------------------+🏋️ Hands-On Exercise
🎯 The Challenge: Extend <media-card> with Interactive Like Counter
Instructions:
- Use the
<media-card>architecture from this lesson. - In the Light DOM action slot, inject an interactive
<button slot="actions" class="like-btn">❤️ <span class="like-count">0</span> Likes</button>. - Add a click event handler to the button that increments the like counter and dispatches a custom composed event
'card-liked'with the new total. - Listen for
'card-liked'on thedocumentto demonstrate event traversal across shadow DOM boundaries.
🏁 Starter Code Sandbox
⚠️ Common Pitfalls
- Hardcoding Slot Heights Without Aspect Ratios: Fixing media slot heights to
height: 200pxcauses distortion on mobile screens. Always use modern CSSaspect-ratio: 16 / 9;on the slot wrapper. - Forgetting Fallback Dimensions: If an SVG fallback inside
<slot name="media">has no explicitwidth,height, orviewBox, it may collapse to 0 pixels in some browser rendering engines. - Unnecessary Wrapper
<div>Bloat in Consumer Markup: Consumers do not need to wrap every text element in a<div>to slot it; simple<h3 slot="header">or<button slot="actions">tags slot directly.
💡 Pro Tips
- CSS Part Exposure (
::part): In addition to slots, expose structural styling hooks usingpart="header",part="media", andpart="footer"on internal shadow wrappers so design system consumers can customize padding and background styles seamlessly. - Constructable Stylesheets Integration: In production enterprise libraries, combine
<template>stamping withshadowRoot.adoptedStyleSheets = [sharedSheet]to share CSS rule caches across thousands of<media-card>instances.
📌 Key Takeaways
- Multi-slot composition enables complex enterprise components with clean, declarative consumer APIs.
- Declarative fallback content allows components to render beautifully even when optional slots are omitted.
- Use
slotchangeto dynamically synchronize container visibility when optional toolbars are empty. ::slotted([slot="media"])ensures projected media elements automatically conform to component layout rules.- Static template compilation maximizes memory reuse and delivers near-instantaneous component instantiation.
- --
Question 1 / 3
Why is compiling the master <template> as a static class property (static template = ...) a recommended architectural pattern for Web Components?
Topic: HTML Fundamentals
Question 2 / 3
How can a <media-card> automatically hide its footer action bar container when the consumer provides no elements matching slot="actions"?
Topic: HTML Fundamentals
Question 3 / 3
Which CSS selector inside the component's Shadow DOM ensures that any image projected into slot="media" fills the 16:9 container without distortion?
Topic: HTML Fundamentals