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)
Secondary (foreground)
Tertiary (backgrounds)
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 for more options.
Code
<!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
Secondary
Tertiary
.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 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 for what each class affects.
Code
<!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>