Components

Images & media slots

Still and direct MP4 patterns share one slot API: .background-image / .background-video and .aspect. Image width caps use .image-* / .thumbnail / .medium / .large. YouTube: ws-youtube; compare: Image comparison; avatars: Facepile.

Download & setup

Load the kit from Get Started; use the style guide for utilities and tokens while wiring this component.

Default implementation

Sizing: tokens and convenience classes

Apply image-xxs through image-l (or image-full) directly on the img, or use the thumbnail, medium, and large shortcuts for common editorial widths. Set explicit width and height to match the asset and reduce layout shift.

Width tokens

Same file family, different max-width caps (rounded corners for the demo only).

Sample, extra small

image-xxs

Sample, small

image-s

Sample, medium

image-m

Shortcuts

thumbnail, medium, and large on img for documentation and content columns.

Thumbnail sample

img.thumbnail

Medium sample

img.medium

Large sample

img.large

Markup

<img class="image-m round" src="/media/hero.jpg" width="1200" height="750" alt="Product workspace" />
<img class="thumbnail round" src="/media/avatar.jpg" width="120" height="120" alt="Jane Lee" />

Configuration options

Each variant keeps the same markup contract as the default; add only the classes or attributes named in the heading.

Layered still: background-image

The child sits in an absolutely positioned slot and fills the parent with object-fit: cover. The parent must establish height (height-*, or an aspect box) and usually hide-overflow and relative. Child may be img, video, or iframe. On top, use an overlay (see the style guide) with tint-light / tint-dark as needed, here flex-column and align-bottom pin a line to the lower edge.

Headline or card copy layers above the still.

Frame: relative layer-bottom height-30 hide-overflow round; layer-bottom contains background-image’s z-index:-1 so a fill-light preview shell does not paint over the still. Content: overlay relative tint-dark flex-column and align-bottom on the line. height-100 is the full-viewport min-height utility, not this block.

Markup

<div class="relative layer-bottom height-30 hide-overflow round">
  <div class="background-image" aria-hidden="true">
    <img src="/media/background.jpg" width="1600" height="900" alt="" />
  </div>
  <div class="overlay relative tint-dark flex-column pad">
    <p class="text-s text-white text-shadow align-bottom">…</p>
  </div>
</div>

Alignment within a column

Use image-left, image-center, or image-right on a block-level wrapper (e.g. p or figure) to align a smaller still in the column’s inline direction, typical for avatars and inline figures next to type.

Left-aligned sample

Centered sample
Right-aligned sample

Markup

<figure class="image-center">
  <img class="thumbnail round" src="/media/author.jpg" width="200" height="200" alt="Author portrait" />
</figure>

Fixed aspect ratio: aspect

Combine aspect with aspect-16-9, aspect-1, or aspect-3-4 so the box holds ratio while the img or video covers the interior. Useful for card grids and predictable crop regions.

Wide sample

16:9

Square sample

1:1 (width capped for layout)

Markup

<div class="aspect aspect-16-9 round">
  <img src="/media/cover.jpg" width="800" height="450" alt="Product overview" />
</div>

Direct MP4: inline player

No custom element for self-hosted video — use native <video>. Put it in .aspect for a responsive 16:9 frame with object-fit: cover, or in .background-image when the parent uses height-* instead of aspect ratio. Add controls, playsinline, and preload="metadata"; optional poster for a still before play. For YouTube (poster, click-to-load), use ws-youtube instead.

aspect-16-9 · controls

Markup

<div class="aspect aspect-16-9 round hide-overflow">
  <video src="/media/demo.mp4" controls playsinline preload="metadata" poster="/media/demo-poster.jpg" title="Product overview"></video>
</div>

Direct MP4: ambient loop

Decorative motion: same .background-image slot as a still, or .background-video on a full hero section. Use autoplay muted loop playsinline and preload="metadata". Prefer MP4 over YouTube for full-bleed heroes — native video respects object-fit: cover without iframe letterboxing (see the YouTube page).

Copy layers above the loop, same as a background still.

Full-viewport hero: wrap with .background-video on the section (see home page and style guide Media).

Markup

<!-- Card / band loop -->
<div class="relative hide-overflow round height-30">
  <div class="background-image" aria-hidden="true">
    <video src="/media/ambient.mp4" autoplay muted loop playsinline preload="metadata"></video>
  </div>
  <div class="overlay relative tint-dark pad">…</div>
</div>

<!-- Hero -->
<section class="height-75 relative">
  <div class="background-video">
    <video src="/media/hero.mp4" autoplay muted loop playsinline preload="metadata"></video>
  </div>
  <div class="overlay">…</div>
</section>

When to use

  • Product marketing: consistent art sizes in grids, card rails, and hero layers.
  • Editorial: thumbnail / medium / large for inline figures without bespoke CSS per article.
  • Commerce and content: aspect boxes and alignment for product shots and inline figures before you add carousels or overlays.
  • Hero and band motion: self-hosted MP4 in <code>.background-video</code> or <code>.background-image</code>; inline explainers with <code>&lt;video controls&gt;</code> in <code>.aspect</code>.

Implementation notes

  • There is no ws-video element — self-hosted files use <video> in .background-image, .background-video, or .aspect. YouTube: <ws-youtube> on the YouTube component page.
  • Embeds in .background-image / .background-video fill the slot with object-fit: cover; the parent must set height (height-*) or use .aspect for ratio.
  • Use the standalone object-cover utility when you need object-fit: cover without the absolute background-image pattern.
  • img.medium and img.large also apply max-width rules, verify composition on small breakpoints.
  • For stacked stills with a drag handle, use the Image comparison component rather than reimplementing the scrub layer.
  • Overlapping round portrait rows (facepiles) use .wckd-facepile, see the Facepile component page.

Developer checklist

  • Meaningful alt for informative images; empty alt only when the image is decorative.
  • Replace placeholder URLs with production src and add srcset / sizes for responsive and retina delivery.
  • Respect prefers-reduced-motion when animating on top of these stills; avoid parallax in background-image slots.
  • For <video>: playsinline for mobile; muted when using autoplay; title (and captions when speech matters); pause or hide ambient loops when prefers-reduced-motion is set.

← All components