Styling & Themes

Customize the appearance of the MP4E Player with CSS.

Overview

The MP4E Player is fully customizable through CSS. You can use CSS variables for quick theming, override specific classes for fine-grained control, or build entirely custom controls.

Basic styling
// Import default styles
import '@mp4e/react/styles.css';

// Add custom styles via className or style prop
<MP4EPlayer
  src="/video.mp4"
  className="my-custom-player"
  style={{ maxWidth: '800px', margin: '0 auto' }}
/>
Import Default Styles
Always import the default stylesheet first, then add your customizations. This ensures all base styles are in place.

CSS Classes

All player elements use BEM-style class names prefixed with mp4e-.

CSS class reference
1/* Container Classes */
2.mp4e-player { } /* Root container */
3.mp4e-player--fullscreen { } /* Fullscreen mode */
4.mp4e-player--playing { } /* Video is playing */
5.mp4e-player--paused { } /* Video is paused */
6.mp4e-player--loading { } /* Video is loading */
7.mp4e-player--error { } /* Error state */
8
9/* Video Element */
10.mp4e-video { } /* Video element */
11.mp4e-poster { } /* Poster image */
12
13/* Object Layer */
14.mp4e-objects { } /* Objects container (SVG) */
15.mp4e-object { } /* Individual object */
16.mp4e-object--highlighted { } /* Highlighted object */
17.mp4e-object--hovered { } /* Hovered object */
18.mp4e-object-label { } /* Object label tooltip */
19
20/* Overlays */
21.mp4e-overlays { } /* Overlays container */
22.mp4e-overlay { } /* Individual overlay */
23.mp4e-overlay--visible { } /* Visible overlay */
24.mp4e-overlay--attached { } /* Attached to object */
25.mp4e-overlay--fixed { } /* Fixed position */
26
27/* Controls */
28.mp4e-controls { } /* Controls container */
29.mp4e-controls--hidden { } /* Auto-hidden controls */
30.mp4e-controls-bottom { } /* Bottom controls bar */
31.mp4e-controls-center { } /* Center controls (big play) */
32
33/* Progress Bar */
34.mp4e-progress { } /* Progress bar container */
35.mp4e-progress-bar { } /* Full bar */
36.mp4e-progress-loaded { } /* Buffered portion */
37.mp4e-progress-played { } /* Played portion */
38.mp4e-progress-handle { } /* Scrubber handle */
39.mp4e-progress-tooltip { } /* Time tooltip */
40
41/* Buttons */
42.mp4e-button { } /* Base button */
43.mp4e-play-button { } /* Play/pause toggle */
44.mp4e-mute-button { } /* Mute toggle */
45.mp4e-fullscreen-button { } /* Fullscreen toggle */
46.mp4e-volume-slider { } /* Volume slider */
47
48/* Loading & Error */
49.mp4e-loading { } /* Loading spinner */
50.mp4e-error { } /* Error message */
51
52/* Modal */
53.mp4e-modal-backdrop { } /* Modal backdrop */
54.mp4e-modal { } /* Modal container */
55.mp4e-modal-close { } /* Modal close button */

CSS Variables

CSS custom properties (variables) provide the easiest way to customize colors, sizes, and transitions.

CSS variables reference
1:root {
2 /* Primary Colors */
3 --mp4e-color-primary: #3b82f6;
4 --mp4e-color-primary-hover: #2563eb;
5
6 /* Background Colors */
7 --mp4e-bg-controls: rgba(0, 0, 0, 0.8);
8 --mp4e-bg-tooltip: rgba(0, 0, 0, 0.9);
9 --mp4e-bg-modal: rgba(0, 0, 0, 0.7);
10
11 /* Text Colors */
12 --mp4e-text-primary: #ffffff;
13 --mp4e-text-secondary: rgba(255, 255, 255, 0.7);
14
15 /* Object Highlights */
16 --mp4e-object-stroke: #3b82f6;
17 --mp4e-object-stroke-width: 2px;
18 --mp4e-object-fill: rgba(59, 130, 246, 0.1);
19 --mp4e-object-fill-hover: rgba(59, 130, 246, 0.2);
20
21 /* Progress Bar */
22 --mp4e-progress-bg: rgba(255, 255, 255, 0.2);
23 --mp4e-progress-loaded: rgba(255, 255, 255, 0.4);
24 --mp4e-progress-played: #3b82f6;
25 --mp4e-progress-height: 4px;
26 --mp4e-progress-height-hover: 6px;
27
28 /* Controls */
29 --mp4e-controls-padding: 12px;
30 --mp4e-controls-gap: 8px;
31 --mp4e-icon-size: 24px;
32 --mp4e-icon-size-large: 32px;
33
34 /* Transitions */
35 --mp4e-transition-fast: 150ms ease;
36 --mp4e-transition-normal: 250ms ease;
37
38 /* Border Radius */
39 --mp4e-radius-sm: 4px;
40 --mp4e-radius-md: 8px;
41 --mp4e-radius-lg: 12px;
42
43 /* Shadows */
44 --mp4e-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.1);
45 --mp4e-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.15);
46 --mp4e-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.2);
47}
Scoped Variables
You can scope variables to a specific player by applying them to a wrapper class instead of :root.

Themes

The player comes with dark and light themes. Set the theme via the theme prop.

Using themes
<MP4EPlayer
  src="/video.mp4"
  theme="dark"  // or "light" or "auto"
/>

Dark Theme (Default)

Dark theme variables
/* Dark Theme (Default) */
.mp4e-theme-dark {
  --mp4e-color-primary: #3b82f6;
  --mp4e-bg-controls: rgba(0, 0, 0, 0.8);
  --mp4e-text-primary: #ffffff;
  --mp4e-text-secondary: rgba(255, 255, 255, 0.7);
  --mp4e-progress-bg: rgba(255, 255, 255, 0.2);
}

Light Theme

Light theme variables
/* Light Theme */
.mp4e-theme-light {
  --mp4e-color-primary: #2563eb;
  --mp4e-bg-controls: rgba(255, 255, 255, 0.95);
  --mp4e-text-primary: #1f2937;
  --mp4e-text-secondary: rgba(31, 41, 55, 0.7);
  --mp4e-progress-bg: rgba(0, 0, 0, 0.1);
  --mp4e-progress-loaded: rgba(0, 0, 0, 0.2);
}

Object Styling

Customize how tracked objects appear and respond to interactions.

Object highlight customization
1/* Custom object highlighting */
2.mp4e-object {
3 cursor: pointer;
4 transition: all var(--mp4e-transition-fast);
5}
6
7.mp4e-object polygon,
8.mp4e-object rect {
9 stroke: var(--mp4e-object-stroke);
10 stroke-width: var(--mp4e-object-stroke-width);
11 fill: var(--mp4e-object-fill);
12}
13
14.mp4e-object--hovered polygon,
15.mp4e-object--hovered rect {
16 stroke-width: 3px;
17 fill: var(--mp4e-object-fill-hover);
18}
19
20/* Different colors for object groups */
21.mp4e-object[data-group="products"] polygon {
22 stroke: #10b981;
23 fill: rgba(16, 185, 129, 0.1);
24}
25
26.mp4e-object[data-group="people"] polygon {
27 stroke: #8b5cf6;
28 fill: rgba(139, 92, 246, 0.1);
29}
30
31/* Custom labels */
32.mp4e-object-label {
33 background: var(--mp4e-bg-tooltip);
34 color: var(--mp4e-text-primary);
35 padding: 4px 8px;
36 border-radius: var(--mp4e-radius-sm);
37 font-size: 12px;
38 font-weight: 500;
39 box-shadow: var(--mp4e-shadow-md);
40}

Controls Styling

Customize or replace the built-in video controls.

Custom controls
1/* Hide default controls */
2.mp4e-player.custom-controls .mp4e-controls {
3 display: none;
4}
5
6/* Custom progress bar */
7.my-progress-bar {
8 height: 4px;
9 background: var(--mp4e-progress-bg);
10 border-radius: 2px;
11 cursor: pointer;
12}
13
14.my-progress-bar:hover {
15 height: 6px;
16}
17
18.my-progress-played {
19 height: 100%;
20 background: var(--mp4e-color-primary);
21 border-radius: inherit;
22 transition: width 100ms linear;
23}
24
25/* Custom play button */
26.my-play-button {
27 width: 64px;
28 height: 64px;
29 border-radius: 50%;
30 background: var(--mp4e-color-primary);
31 border: none;
32 cursor: pointer;
33 display: flex;
34 align-items: center;
35 justify-content: center;
36 transition: transform var(--mp4e-transition-fast),
37 background var(--mp4e-transition-fast);
38}
39
40.my-play-button:hover {
41 transform: scale(1.1);
42 background: var(--mp4e-color-primary-hover);
43}
44
45.my-play-button svg {
46 width: 24px;
47 height: 24px;
48 fill: white;
49 margin-left: 4px; /* Visual centering for play icon */
50}

Responsive Design

Make the player responsive across screen sizes.

Responsive styles
1/* Responsive player */
2.mp4e-player {
3 width: 100%;
4 max-width: 1200px;
5 margin: 0 auto;
6}
7
8/* Mobile: smaller controls */
9@media (max-width: 640px) {
10 .mp4e-player {
11 --mp4e-controls-padding: 8px;
12 --mp4e-icon-size: 20px;
13 --mp4e-progress-height: 3px;
14 }
15
16 .mp4e-object-label {
17 font-size: 10px;
18 padding: 2px 6px;
19 }
20
21 /* Hide some controls on mobile */
22 .mp4e-volume-slider,
23 .mp4e-playback-rate {
24 display: none;
25 }
26}
27
28/* Tablet */
29@media (min-width: 641px) and (max-width: 1024px) {
30 .mp4e-player {
31 --mp4e-icon-size: 22px;
32 }
33}
34
35/* Fixed aspect ratio container */
36.player-container {
37 position: relative;
38 width: 100%;
39 padding-bottom: 56.25%; /* 16:9 */
40 height: 0;
41}
42
43.player-container .mp4e-player {
44 position: absolute;
45 top: 0;
46 left: 0;
47 width: 100%;
48 height: 100%;
49}

Complete Examples

A comprehensive custom theme example:

Complete branded theme
1/* Complete custom theme */
2.my-branded-player {
3 /* Brand colors */
4 --mp4e-color-primary: #ec4899;
5 --mp4e-color-primary-hover: #db2777;
6
7 /* Dark, rounded aesthetic */
8 --mp4e-bg-controls: rgba(17, 24, 39, 0.95);
9 --mp4e-radius-md: 16px;
10 --mp4e-radius-lg: 24px;
11
12 /* Glassy overlays */
13 --mp4e-bg-tooltip: rgba(17, 24, 39, 0.8);
14 --mp4e-bg-modal: rgba(17, 24, 39, 0.85);
15 backdrop-filter: blur(12px);
16
17 /* Custom shadows */
18 --mp4e-shadow-md: 0 4px 20px rgba(236, 72, 153, 0.2);
19
20 /* Smooth animations */
21 --mp4e-transition-normal: 300ms cubic-bezier(0.4, 0, 0.2, 1);
22}
23
24/* Player container */
25.my-branded-player {
26 border-radius: var(--mp4e-radius-lg);
27 overflow: hidden;
28 box-shadow: var(--mp4e-shadow-lg);
29}
30
31/* Gradient progress bar */
32.my-branded-player .mp4e-progress-played {
33 background: linear-gradient(90deg, #ec4899, #8b5cf6);
34}
35
36/* Animated object highlights */
37.my-branded-player .mp4e-object polygon {
38 stroke: #ec4899;
39 animation: pulse 2s ease-in-out infinite;
40}
41
42@keyframes pulse {
43 0%, 100% { stroke-opacity: 0.8; }
44 50% { stroke-opacity: 1; }
45}
46
47/* Custom loading spinner */
48.my-branded-player .mp4e-loading {
49 border-color: transparent;
50 border-top-color: #ec4899;
51 border-right-color: #ec4899;
52}