Built on the open web
Every browser API and CSS feature the player calls, and what each one is for. A music player touches a lot of them, which is part of the point.
Media
- HTMLMediaElementOne audio and one video element for the whole page, which every control drives.
- TimeRangesShows how much of the file is loaded past the playhead.
- Screen Wake LockKeeps the screen on while a video plays in Now Playing, and only then.
- VibrationA short tick under the thumb on play and pause.
- Network InformationRespects Data Saver by fetching nothing before a press.
- Media SessionGives the lock screen and headphones the track's title, artwork and controls.
- Remote PlaybackShows the cast button only when a Chromecast or AirPlay target is in reach.
- Web AudioReads the signal that lights the filament.
- AnalyserNodeTurns the signal into one heat value and three band levels, every frame.
- Page VisibilityMoves a playing video to audio when the page goes to the background.
- Lazy loadingFetches list thumbnails only as they scroll into view.
- Async decodingDecodes cover art off the main thread so the seek line does not stutter.
Interface
- Pointer EventsOne gesture helper for swiping the bar and dragging the sheets.
- Web AnimationsBreathes the filament where there is no signal to follow.
- requestAnimationFrameMoves the seek line and the filament every frame, not four times a second.
- Web ShareOpens the system share sheet with the track's title and the post link.
- ClipboardCopies the link where there is no share sheet.
- inertMakes Now Playing a real modal: nothing behind it can take focus.
- matchMediaReads the same breakpoint and motion preference the stylesheet uses.
- scrollIntoViewBrings the playing track into view when Up next opens.
Platform
- ES modulesThe shipped file is the source, loaded as a module with no build step.
- Dynamic importLoads the Listen app only on the page that holds the block.
- HistoryBack closes Now Playing, and the Listen app navigates without a page load.
- Web StorageCarries the queue and position to the next page, and remembers the volume.
- FetchSwaps library views in from the REST route without a page load.
- Navigation TimingTells a reload from a link, so a reload never autoplays.
- pagehideCaptures the exact position when the listener leaves the page.
- pageshowRestarts the frame loop after a Back from the back-forward cache.
- ARIA dialogNow Playing is a named modal dialog with Escape and focus return.
Styling
- @propertyRegisters the filament's heat as a real number, so it can animate.
- color-mix()Tints rows, pills and the seek line from the theme's own text colour.
- oklabMixes the filament's colour from red through amber to white without muddy midtones.
- Container queriesSizes the cover from the stage it sits in, not the viewport.
- :has()Styles a parent from a child's state, without the script toggling classes.
- env() safe areasKeeps the bar and Now Playing clear of the notch and the home indicator.
- text-wrapBalances a long title in the Listen app so no word is left alone.
- Variable fontsShips each font as one file covering every weight the player asks for.
Behaviour
- prefers-reduced-motionStops the equalizer, the filament and the sliding sheets when the system asks.
- prefers-reduced-transparencyRemoves the translucent wash and the bloom when the system asks.
- clip-pathHides the Song and Video labels on a phone, but not from screen readers.
- aspect-ratioReserves the video's box and each record cover's square before anything loads.
- accent-colorRecolours the browser's own volume slider to the player's white.
- touch-actionClaims the swipes and drags so the browser does not scroll instead.
- overscroll-behaviorKeeps the Up next list's scroll from moving the post behind it.
- :focus-visibleShows a focus ring for the keyboard and not after a tap.