Skip to content

Theming ​

py-player supports three customization layers that stack on top of each other: theme presets, CSS variable overrides, and CSS Parts.

Theme Presets ​

Set the theme attribute to apply a color preset:

html
<py-audio src="audio.mp3" theme="dark"></py-audio>
<py-video src="video.mp4" theme="midnight"></py-video>
<py-player src="media.mp3" theme="nord"></py-player>
PresetDescription
autoFollows system prefers-color-scheme (default)
lightWhite background, light tones
darkDark charcoal tones
midnightDeep blue tones
nordNord color palette
sunsetWarm oranges and reds
forestEarthy greens

Accent Color ​

Override the accent color independently of the theme:

html
<py-audio src="audio.mp3" theme="dark" accent="#e07b39"></py-audio>
<py-audio src="audio.mp3" theme="nord" accent="#ff6b6b"></py-audio>

Any valid CSS color works: hex, rgb(), hsl(), named colors.

CSS Variables ​

Override individual design tokens from outside the Shadow DOM:

css
py-audio {
  --py-accent: #e07b39;
  --py-bg: #1a1a2e;
  --py-bg-secondary: #16213e;
  --py-text: #eaeaea;
  --py-radius: 16px;
}

All CSS Variables ​

VariableDefault (light)Description
--py-accent#378ADDAccent/highlight color
--py-bg#ffffffPrimary background
--py-bg-secondary#f5f5f4Secondary background
--py-bg-hover#ede9e0Hover state background
--py-borderrgba(0,0,0,0.08)Border color
--py-text#1a1916Primary text
--py-text-secondary#6b6860Secondary text
--py-text-muted#a8a59eMuted/disabled text
--py-radius10pxBorder radius
--py-font'DM Sans', system-uiFont family

CSS Parts ​

Style specific internal elements from outside the Shadow DOM using ::part():

css
py-audio::part(root) {
  border: 2px solid hotpink;
  border-radius: 20px;
}

py-audio::part(btn-play) {
  background: linear-gradient(135deg, #ff6b6b, #feca57);
  border-radius: 50%;
}

py-audio::part(progress-fill) {
  background: #e07b39;
}

Available Parts ​

Shared (audio + video):

PartDescription
rootOuter container
top-barTitle bar
controlsButton group container
btn-playPlay/pause button
btn-prevPrevious button
btn-nextNext button
progressProgress bar track
progress-fillProgress bar filled portion
progress-thumbProgress bar handle
playlistPlaylist container
playlist-itemIndividual track/chapter item
upload-areaFile upload zone
now-playingCurrent track display

Audio-only:

PartDescription
visualizerVisualizer container
viz-barIndividual frequency bar

Video-only:

PartDescription
video-containerVideo element wrapper
video-controlsBottom controls bar
volume-sliderVolume control
fullscreen-btnFullscreen toggle

Combining Layers ​

Layers stack: preset → CSS variables → CSS Parts.

html
<style>
  #my-player {
    --py-radius: 20px;
    --py-font: 'Georgia', serif;
  }
  #my-player::part(btn-play) {
    width: 48px;
    height: 48px;
    border-radius: 50%;
  }
</style>

<py-audio
  id="my-player"
  src="audio.mp3"
  theme="forest"
  accent="#2d6a4f"
></py-audio>

Layout + Theme Combinations ​

Layout and theme are independent — any layout works with any theme:

html
<py-audio layout="visualizer" theme="midnight" accent="#ff6b6b"></py-audio>
<py-audio layout="podcast"    theme="nord"></py-audio>
<py-audio layout="compact"    theme="sunset" accent="#c0392b"></py-audio>