# Changing the UI with CSS

Use CSS custom properties and shadow parts to match the player to your site.

## Open Video UI

Tip: open your browser's developer console and use the `player` and `THEOplayer` variables to interact with this demo.

### Primary (accent)

Seek bar fill#ffc50fSeek bar thumb#ffc50fCenter play button icon#ffc50f

### Secondary (foreground)

Text#ffffffControl icons#ffffffMenu text#ffffff

### Tertiary (backgrounds)

Control bar gradient end#000000Menu backdrop#000000

Reset

Generated CSS

```css
theoplayer-default-ui {
  --theoplayer-range-bar-color: #ffc50f;
  --theoplayer-range-thumb-background: #ffc50f;
  --theoplayer-center-play-button-icon-color: #ffc50f;
  --theoplayer-text-color: #ffffff;
  --theoplayer-icon-color: #ffffff;
  --theoplayer-menu-color: #ffffff;
  --theoplayer-control-background-gradient-stops: transparent 0%, #000000 100%;
  --theoplayer-menu-backdrop-background: #000000;
}
```

Open Video UI exposes its colors through CSS custom properties such as `--theoplayer-icon-color`, `--theoplayer-menu-color`, `--theoplayer-range-bar-color` and `--theoplayer-control-background-gradient-stops`, grouped below into accent, foreground and background colors. See the [Open Video UI styling example](https://optiview.dolby.com/docs/open-video-ui/web/examples/styling/) for more options.

Code

demo.html

```html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Changing the UI with CSS</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link href="https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet" />
    <style>
      html,
      body {
        margin: 0;
        padding: 0;
      }

      theoplayer-default-ui:not(:defined) {
        display: inline-block;
        box-sizing: border-box;
      }

      theoplayer-default-ui {
        width: 100%;
        aspect-ratio: 16 / 9;
        font-family: 'Noto Sans', sans-serif;
        background: #000;
        --theoplayer-range-bar-color: #ffc50f;
        --theoplayer-range-thumb-background: #ffc50f;
        --theoplayer-center-play-button-icon-color: #ffc50f;
        --theoplayer-text-color: #ffffff;
        --theoplayer-icon-color: #ffffff;
        --theoplayer-range-thumb-height: 18px;
        --theoplayer-range-thumb-width: 18px;
        --theoplayer-range-track-height: 6px;
        --theoplayer-control-background-gradient-stops: transparent 0%, #000000 100%;
        --theoplayer-menu-backdrop-background: rgb(0 0 0 / 85%);
      }
    </style>
    <script src="https://cdn.theoplayer.com/dash/theoplayer/THEOplayer.js"></script>
    <script nomodule src="https://unpkg.com/@theoplayer/web-ui@2/polyfills"></script>
    <script async src="https://unpkg.com/@theoplayer/web-ui@2"></script>
  </head>
  <body>
    <!--
      libraryLocation: For demonstration purposes, we use the THEOplayer CDN.
      For production use, host the library yourself and update this URL and the script above.

      licenseUrl: Point this to your license file, or replace it with a license property.
    -->
    <theoplayer-default-ui
      id="player-ui"
      configuration='{"libraryLocation":"https://cdn.theoplayer.com/dash/theoplayer/","licenseUrl":"../../../../theoplayer-license.txt"}'
      source='{"sources":{"src":"https://cdn.theoplayer.com/video/big_buck_bunny/big_buck_bunny_metadata.m3u8","type":"application/x-mpegurl"},"poster":"https://cdn.theoplayer.com/video/big_buck_bunny/poster.jpg","metadata":{"title":"Big Buck Bunny"}}'
    ></theoplayer-default-ui>
    <script src="../utils.js"></script>
    <script>
      const ui = document.querySelector('#player-ui');
      const hexPattern = /^#[0-9a-f]{6}$/i;

      function isHex(value) {
        return typeof value === 'string' && hexPattern.test(value);
      }

      onPlayerReady(() => {
        onParentMessage('ui-colors', (message) => {
          const colors = message.colors;
          if (typeof colors !== 'object' || colors == null) return;
          if (isHex(colors['range-bar-color'])) ui.style.setProperty('--theoplayer-range-bar-color', colors['range-bar-color']);
          if (isHex(colors['range-thumb-background'])) ui.style.setProperty('--theoplayer-range-thumb-background', colors['range-thumb-background']);
          if (isHex(colors['center-play-button-icon-color']))
            ui.style.setProperty('--theoplayer-center-play-button-icon-color', colors['center-play-button-icon-color']);
          if (isHex(colors['text-color'])) ui.style.setProperty('--theoplayer-text-color', colors['text-color']);
          if (isHex(colors['icon-color'])) ui.style.setProperty('--theoplayer-icon-color', colors['icon-color']);
          if (isHex(colors['menu-color'])) ui.style.setProperty('--theoplayer-menu-color', colors['menu-color']);
          if (isHex(colors['control-background-end']))
            ui.style.setProperty('--theoplayer-control-background-gradient-stops', `transparent 0%, ${colors['control-background-end']} 100%`);
          if (isHex(colors['menu-backdrop-background']))
            ui.style.setProperty('--theoplayer-menu-backdrop-background', colors['menu-backdrop-background']);
        });
      });
    </script>
  </body>
</html>
```

## Default UI

Tip: open your browser's developer console and use the `player` and `THEOplayer` variables to interact with this demo.

### Primary

Primary color#ffc50fPrimary background text#000000Primary background#ffc50f

### Secondary

Secondary color#ffffffSecondary background text#000000Secondary background#ffffff

### Tertiary

Tertiary color#000000Tertiary background text#ffffffTertiary background#000000

Reset

Generated CSS

```css
.theoplayer-skin .theo-primary-color,
.theoplayer-skin .vjs-selected {
  color: #ffc50f !important;
}
.theoplayer-skin .theo-primary-background {
  color: #000000 !important;
  background-color: #ffc50f !important;
}
.theoplayer-skin .theo-secondary-color {
  color: #ffffff !important;
}
.theoplayer-skin .theo-secondary-background {
  color: #000000 !important;
  background-color: #ffffff !important;
}
.theoplayer-skin .theo-tertiary-color {
  color: #000000 !important;
}
.theoplayer-skin .theo-tertiary-background {
  color: #ffffff !important;
  background-color: #000000 !important;
}
```

The [Default UI](https://optiview.dolby.com/docs/theoplayer/ui/web/default-ui.md) groups its themed elements into six color classes: `.theo-primary-color` and `.theo-primary-background`, `.theo-secondary-color` and `.theo-secondary-background`, and `.theo-tertiary-color` and `.theo-tertiary-background`, plus `.vjs-selected` for selected menu items. Override these classes to recolor every element at once; see [UI skinning](https://optiview.dolby.com/docs/theoplayer/ui/web/ui-skinning.md) for what each class affects.

Code

default-ui.html

```html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Changing the Default UI with CSS</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="https://cdn.theoplayer.com/dash/theoplayer/ui.css" />
    <script src="https://cdn.theoplayer.com/dash/theoplayer/THEOplayer.js"></script>
    <script src="../utils.js"></script>
    <style>
      html,
      body {
        margin: 0;
        padding: 0;
      }

      .theoplayer-skin {
        width: 100%;
        --primary-color: #ffc50f;
        --primary-background-text: #000000;
        --primary-background: #ffc50f;
        --secondary-color: #ffffff;
        --secondary-background-text: #000000;
        --secondary-background: #ffffff;
        --tertiary-color: #000000;
        --tertiary-background-text: #ffffff;
        --tertiary-background: #000000;
      }

      .theoplayer-skin .theo-primary-color,
      .theoplayer-skin .vjs-selected {
        color: var(--primary-color) !important;
      }

      .theoplayer-skin .theo-primary-background {
        color: var(--primary-background-text) !important;
        background-color: var(--primary-background) !important;
      }

      .theoplayer-skin .theo-secondary-color {
        color: var(--secondary-color) !important;
      }

      .theoplayer-skin .theo-secondary-background {
        color: var(--secondary-background-text) !important;
        background-color: var(--secondary-background) !important;
      }

      .theoplayer-skin .theo-tertiary-color {
        color: var(--tertiary-color) !important;
      }

      .theoplayer-skin .theo-tertiary-background {
        color: var(--tertiary-background-text) !important;
        background-color: var(--tertiary-background) !important;
      }
    </style>
  </head>
  <body>
    <div id="player" class="video-js theoplayer-skin vjs-16-9"></div>
    <script>
      var player = new THEOplayer.Player(document.querySelector('#player'), {
        libraryLocation: 'https://cdn.theoplayer.com/dash/theoplayer/',
        licenseUrl: '../../../../theoplayer-license.txt',
      });
      player.source = {
        sources: [
          {
            src: 'https://cdn.theoplayer.com/video/big_buck_bunny/big_buck_bunny_metadata.m3u8',
            type: 'application/x-mpegurl',
          },
        ],
        poster: 'https://cdn.theoplayer.com/video/big_buck_bunny/poster.jpg',
        metadata: { title: 'Big Buck Bunny' },
      };

      var colorKeys = [
        'primary-color',
        'primary-background-text',
        'primary-background',
        'secondary-color',
        'secondary-background-text',
        'secondary-background',
        'tertiary-color',
        'tertiary-background-text',
        'tertiary-background',
      ];

      onParentMessage('ui-colors', (message) => {
        var colors = message.colors;
        if (typeof colors !== 'object' || colors == null) return;
        var skin = document.querySelector('.theoplayer-skin');
        colorKeys.forEach(function (key) {
          var value = colors[key];
          if (typeof value === 'string' && /^#[0-9a-f]{6}$/i.test(value)) {
            skin.style.setProperty('--' + key, value);
          }
        });
      });
    </script>
  </body>
</html>
```
