Skip to content

Video

A figure whose media is a muted, looping clip with a play and pause button. It plays while on screen and never autoplays for people who prefer reduced motion.

CSS
css/components/video.css
JS
js/components/video.js

01 — Example

Clip

Replace the artwork with your clip’s <source>. The poster frame shows until it plays.

Tidal — motion reel, 0:42.Fig. 3

02 — Usage

Use it for

  • Short silent loops: a motion reel, a product in use.

Avoid

  • Video with sound or speech. Use a player with controls and captions.
  • Several loops playing at once in view.

03 — Accessibility

Notes

  • The button’s label follows the state: “Play video” or “Pause video”. Once paused by hand, it stays paused.
  • It pauses when scrolled away and never autoplays with reduced motion.

04 — Without Jewel’s JS

What the script does

The script plays the muted clip while it’s on screen, pauses it out of view, never autoplays under reduced motion, and keeps the button in step. The CSS reads only the markup below, so a framework can set it itself and leave out video.js and data-component.

StateSet thisNotes
Playingdata-state="playing" on .videoHides .icon-play, so the pause icon shows.
Pauseddata-state="paused" on .videoHides .icon-pause. Always set one of the two, or both icons show.
Button labelaria-label="Pause video" while playing, "Play video" while pausedOn .video__control.
Clipmuted, playsinline and loop on the <video>, and no autoplayThe script sets muted and playsinline and removes autoplay. loop comes from the markup.

Events and keyboard

  • Set data-state from the video’s play and pause events, so it stays right however playback changes.
  • Play when at least 40% of it is in view and pause when it leaves (the script uses an IntersectionObserver). Don’t autoplay under prefers-reduced-motion, and pause if it turns on.
  • Once someone pauses it by hand, don’t start it again on scroll.