Theming

Master the video player's comprehensive theming system to create custom visual styles that perfectly match your brand identity and design requirements.

The video player's theming system provides complete control over every visual aspect of the interface. From color schemes and typography to spacing and border radius values, you can customize the player to seamlessly integrate with your application's design language. Whether you're using the built-in themes or creating entirely custom designs, the theming system offers the flexibility you need.

Understanding the Theme System

The player's theme system operates on a hierarchical structure where you can override specific properties while inheriting others from the defaults. This approach allows you to customize exactly what you need without having to redefine every visual property. The theme object encompasses colors, typography, spacing, and border radius values, each controlling different aspects of the player's appearance.

When you pass a theme to the player, it intelligently merges your customizations with the default theme values. This means you only need to specify the properties you want to change, and the player automatically fills in the rest with sensible defaults. This merge-based approach simplifies theme creation while maintaining flexibility.

Theme Architecture: The theme system divides visual properties into logical categories. The colors object handles all color-related styling including backgrounds, text, accents, and component-specific colors. The fonts object manages typography including font families and size scales. The borderRadius object controls corner rounding for various UI elements. The spacing object defines consistent padding and margin values throughout the interface.

Built-in Themes

The player ships with two professionally designed themes that cover the most common use cases: a dark theme optimized for low-light viewing and a light theme suitable for bright environments or applications with light color schemes.

Using the Dark Theme

The dark theme is the default and requires no additional configuration. It features deep backgrounds with carefully calibrated contrast ratios for optimal readability.

src/components/VideoPlayer.jsx
import { CustomVideoPlayer } from "@ntxmjs/react-custom-video-player";

function VideoPlayer() {
  return (
    <CustomVideoPlayer
      src="https://example.com/video.m3u8"
      poster="https://example.com/poster.jpg"
      icons={playerIcons}
      theme="dark"
    />
  );
}

The dark theme uses charcoal backgrounds with subtle gradients, white text with reduced opacity for secondary elements, vibrant blue accents for interactive elements, and semi-transparent overlays for controls that don't obscure video content. This combination creates a professional appearance that works well in theaters, home entertainment systems, and applications designed for extended viewing sessions.

Using the Light Theme

The light theme provides excellent visibility in well-lit environments and integrates naturally with applications using light color schemes.

src/components/VideoPlayer.jsx
import { CustomVideoPlayer } from "@ntxmjs/react-custom-video-player";

function VideoPlayer() {
  return (
    <CustomVideoPlayer
      src="https://example.com/video.m3u8"
      poster="https://example.com/poster.jpg"
      icons={playerIcons}
      theme="light"
    />
  );
}

The light theme employs clean white and light gray backgrounds, dark text with sufficient contrast for readability, softer accent colors that work against light backgrounds, and subtle shadows for depth perception. This theme works particularly well in educational content, business applications, and sites with predominantly light interfaces.

Theme Selection Guidance:

Choose your theme based on your application's overall design and the viewing environment. Dark themes reduce eye strain in low-light conditions and work well for entertainment content. Light themes provide better visibility in bright environments and create a more approachable feel for educational or professional content.

Creating Custom Themes

Custom themes allow you to align the player perfectly with your brand identity. You can create themes that range from subtle variations on the built-in themes to completely unique visual styles.

Basic Color Customization

Start with a simple color customization that changes the accent color to match your brand.

src/components/BrandedVideoPlayer.jsx
import { CustomVideoPlayer } from "@ntxmjs/react-custom-video-player";

function BrandedVideoPlayer() {
  const customTheme = {
    colors: {
      accent: "#ff6b35",
      accentHover: "#ff8555",
    },
  };

  return (
    <CustomVideoPlayer
      src="https://example.com/video.m3u8"
      poster="https://example.com/poster.jpg"
      icons={playerIcons}
      theme={customTheme}
    />
  );
}

This minimal customization changes only the accent color used for progress bars, active states, and interactive elements while inheriting all other properties from the default dark theme. The accent color applies to most interactive elements, while accentHover provides visual feedback when users hover over controls.

Color Selection Strategy: When choosing accent colors, ensure they provide sufficient contrast against the background. The WCAG recommends a contrast ratio of at least 4.5:1 for normal text and 3:1 for large text. Use tools like WebAIM's contrast checker to verify your color choices meet accessibility standards.

Comprehensive Theme Object

For complete control, define all theme properties. Here's an example of a comprehensive custom theme with a warm color palette.

src/components/WarmThemedPlayer.jsx
import { CustomVideoPlayer } from "@ntxmjs/react-custom-video-player";

function WarmThemedPlayer() {
  const warmTheme = {
    colors: {
      background: "linear-gradient(135deg, #2c1810, #3d2415, #2c1810)",
      controlsBottomBG: "linear-gradient(to top, rgba(60, 35, 20, 0.95), rgba(44, 24, 16, 0.85), transparent)",
      backgroundSecondary: "#3d2415",
      backgroundTertiary: "#4a2d1a",
      text: "#ffecd1",
      textMuted: "#c9a882",
      accent: "#ff6b35",
      accentHover: "#ff8555",
      line: "rgba(255, 107, 53, 0.3)",
      controlBg: "rgba(255, 107, 53, 0.1)",
      controlBgHover: "rgba(255, 107, 53, 0.2)",
      controlBorder: "rgba(255, 107, 53, 0.15)",
      panelBg: "linear-gradient(180deg, #4a2d1a, #2c1810)",
      panelBorder: "rgba(255, 107, 53, 0.15)",
      shadowColor: "rgba(0, 0, 0, 0.7)",
      centerBigBtnStyle: {
        background: "rgba(255, 107, 53, 0.45)",
        color: "#ffffff",
        border: "2px solid rgba(255, 133, 85, 0.3)",
        transition: "all 0.2s ease",
        backdropFilter: "blur(2px)",
        cursor: "pointer",
        bgOnMouseEnter: "rgba(255, 107, 53, 0.75)",
        borderOnMouseEnter: "rgba(255, 133, 85, 0.5)",
      },
      customCaptionStyle: {
        width: "max-content",
        maxWidth: "80%",
        background: "rgba(60, 35, 20, 0.9)",
        color: "#ffecd1",
        padding: "4px 8px",
        borderRadius: "4px",
        fontSize: "clamp(10px, 1.6vw, 16px)",
        fontWeight: 400,
        textAlign: "left",
        lineHeight: 1.4,
        pointerEvents: "none",
        transition: "bottom 0.35s ease",
        backdropFilter: "blur(4px)",
        boxShadow: "0 2px 10px rgba(0, 0, 0, 0.6)",
        whiteSpace: "pre-wrap",
        wordWrap: "break-word",
      },
      panelStyling: {
        position: "absolute",
        width: "min(360px, 86vw)",
        maxHeight: "min(65vh, 480px)",
        zIndex: 4,
        overflow: "scroll",
        scrollbarWidth: "none",
        height: "fit-content",
        lowerDeviceMediaQueries: {
          top: "100px",
        },
      },
    },
    fonts: {
      primary: "Inter, system-ui, sans-serif",
      size: {
        small: "11px",
        medium: "13px",
        large: "15px",
      },
    },
    borderRadius: {
      small: "3px",
      medium: "6px",
      large: "10px",
    },
    spacing: {
      small: "6px",
      medium: "10px",
      large: "14px",
    },
  };

  return (
    <CustomVideoPlayer
      src="https://example.com/video.m3u8"
      poster="https://example.com/poster.jpg"
      icons={playerIcons}
      theme={warmTheme}
    />
  );
}

This warm theme creates a cozy, inviting atmosphere with brown and orange tones. It demonstrates how every visual property can be customized to create a cohesive, branded experience. The gradient backgrounds add depth, while the consistent color palette throughout creates visual harmony.

Theme Property Reference

Understanding each theme property helps you make informed customization decisions. Let's explore the purpose and impact of each property in detail.

Color Properties

The colors object contains all color-related properties that define the visual appearance of the player.

Background Colors: The background property sets the main player background, typically using a gradient for visual interest. The controlsBottomBG creates the gradient overlay for the control bar at the bottom of the player. The backgroundSecondary and backgroundTertiary properties define backgrounds for nested UI elements like settings panels and dropdown menus.

colors: {
  background: "linear-gradient(135deg, #1a1a2e, #16213e, #1a1a2e)",
  controlsBottomBG: "linear-gradient(to top, rgba(22, 33, 62, 0.95), rgba(26, 26, 46, 0.85), transparent)",
  backgroundSecondary: "#16213e",
  backgroundTertiary: "#1a1a2e",
}

Text Colors: The text property controls primary text color for labels, timestamps, and menu items. The textMuted property styles secondary text like descriptions and helper text, typically with reduced opacity or a lighter shade.

colors: {
  text: "#e4e4e7",
  textMuted: "#a1a1aa",
}

Interactive Colors: The accent color applies to active elements, progress bars, and selected menu items. The accentHover color provides visual feedback during hover interactions. The line color styles dividers and borders between sections.

colors: {
  accent: "#3b82f6",
  accentHover: "#60a5fa",
  line: "rgba(59, 130, 246, 0.3)",
}

Control Styling: The controlBg and controlBgHover properties style the background of control buttons in default and hover states. The controlBorder defines the border color for control elements. These properties work together to create clear visual hierarchy and feedback.

colors: {
  controlBg: "rgba(59, 130, 246, 0.1)",
  controlBgHover: "rgba(59, 130, 246, 0.2)",
  controlBorder: "rgba(59, 130, 246, 0.15)",
}

Panel Styling: The panelBg property sets the background for settings panels and menus. The panelBorder defines the border color for these panels. The shadowColor creates depth through drop shadows on elevated elements.

colors: {
  panelBg: "linear-gradient(180deg, #16213e, #1a1a2e)",
  panelBorder: "rgba(59, 130, 246, 0.2)",
  shadowColor: "rgba(0, 0, 0, 0.7)",
}

Center Play Button: The centerBigBtnStyle object contains comprehensive styling for the large play button that appears in the center of the player. This object allows detailed customization of this prominent UI element.

colors: {
  centerBigBtnStyle: {
    background: "rgba(59, 130, 246, 0.5)",
    color: "#ffffff",
    border: "2px solid rgba(96, 165, 250, 0.3)",
    transition: "all 0.2s ease",
    backdropFilter: "blur(2px)",
    cursor: "pointer",
    bgOnMouseEnter: "rgba(59, 130, 246, 0.8)",
    borderOnMouseEnter: "rgba(96, 165, 250, 0.5)",
  },
}

The background and bgOnMouseEnter properties control the button's background in default and hover states. The border and borderOnMouseEnter define border styling for both states. The backdropFilter creates a frosted glass effect that works well over video content.

Caption Styling: The customCaptionStyle object provides complete control over subtitle appearance.

colors: {
  customCaptionStyle: {
    width: "max-content",
    maxWidth: "80%",
    background: "rgba(26, 26, 46, 0.9)",
    color: "#e4e4e7",
    padding: "6px 10px",
    borderRadius: "4px",
    fontSize: "clamp(10px, 1.6vw, 16px)",
    fontWeight: 400,
    textAlign: "center",
    lineHeight: 1.4,
    pointerEvents: "none",
    transition: "bottom 0.35s ease",
    backdropFilter: "blur(4px)",
    boxShadow: "0 2px 10px rgba(0, 0, 0, 0.6)",
    whiteSpace: "pre-wrap",
    wordWrap: "break-word",
  },
}

This object controls every aspect of caption rendering from background and text color to sizing and positioning. The fontSize property uses the clamp() function to ensure captions remain readable across all screen sizes. The backdropFilter enhances readability by blurring content behind the captions.

Caption Readability:

Always ensure captions have sufficient contrast against their background. Use semi-transparent backgrounds with backdrop blur for captions that work regardless of video content. Test your caption styling with various video backgrounds to ensure consistent readability.

Panel Positioning: The panelStyling object controls the layout and positioning of settings panels.

colors: {
  panelStyling: {
    position: "absolute",
    width: "min(360px, 86vw)",
    maxHeight: "min(65vh, 480px)",
    zIndex: 4,
    overflow: "scroll",
    scrollbarWidth: "none",
    height: "fit-content",
    lowerDeviceMediaQueries: {
      top: "100px",
    },
  },
}

This object defines how settings panels are positioned and sized. The width and maxHeight properties use the min() function to ensure panels fit on all screen sizes. The lowerDeviceMediaQueries object contains responsive adjustments for smaller devices.

Typography Properties

The fonts object manages all typography-related settings, controlling how text appears throughout the player.

fonts: {
  primary: "Inter, system-ui, -apple-system, sans-serif",
  size: {
    small: "12px",
    medium: "14px",
    large: "16px",
  },
}

The primary property defines the font family used throughout the player. Include fallback fonts to ensure consistent appearance even if the primary font fails to load. System fonts like -apple-system, BlinkMacSystemFont, and system-ui provide native-looking interfaces with excellent performance since they're already available on the user's device.

The size object defines three size scales used consistently throughout the interface. The small size applies to helper text and secondary information. The medium size styles most UI text including menu items and labels. The large size emphasizes important elements like timestamps.

Font Selection Guidelines: Choose fonts that are highly legible at small sizes since player controls often contain compact text. Ensure your chosen font supports all characters you need, including numbers and special symbols. Consider loading performance—web fonts add to page load time, while system fonts are instantly available.

Border Radius Properties

The borderRadius object controls the corner rounding of various UI elements, contributing significantly to the overall visual style.

borderRadius: {
  small: "4px",
  medium: "8px",
  large: "12px",
}

The small radius applies to small UI elements like checkbox borders and input fields. The medium radius styles buttons, menu items, and most interactive elements. The large radius rounds larger components like panels and the player container itself.

Design Impact: Larger border radius values create a softer, more modern appearance but can look unprofessional if overused. Smaller values create sharper, more precise interfaces suitable for professional or technical applications. Maintain consistency by using the same radius value for similar components throughout the interface.

Spacing Properties

The spacing object establishes consistent padding and margin values throughout the player interface.

spacing: {
  small: "8px",
  medium: "12px",
  large: "16px",
}

The small spacing creates tight, compact layouts appropriate for densely packed information. The medium spacing provides comfortable breathing room for most UI elements. The large spacing emphasizes separation between distinct sections.

Spacing Strategy: Consistent spacing creates visual rhythm and makes interfaces feel more organized. Use multiples of your base spacing unit for larger gaps to maintain mathematical harmony. For example, if your small spacing is 8px, use 16px, 24px, and 32px for progressively larger gaps rather than arbitrary values like 18px or 22px.

Dynamic Theme Switching

Implement theme switching to let users choose their preferred appearance or automatically adapt to system preferences.

src/components/ThemeSwitcher.jsx
import { CustomVideoPlayer } from "@ntxmjs/react-custom-video-player";
import { useState, useEffect } from "react";

function ThemeSwitcher() {
  const [isDark, setIsDark] = useState(true);

  useEffect(() => {
    // Detect system preference
    const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
    setIsDark(mediaQuery.matches);

    // Listen for changes
    const handler = (e) => setIsDark(e.matches);
    mediaQuery.addEventListener("change", handler);
    return () => mediaQuery.removeEventListener("change", handler);
  }, []);

  return (
    <div>
      <button onClick={() => setIsDark(!isDark)}>
        Toggle {isDark ? "Light" : "Dark"} Theme
      </button>
      <CustomVideoPlayer
        src="https://example.com/video.m3u8"
        poster="https://example.com/poster.jpg"
        icons={playerIcons}
        theme={isDark ? "dark" : "light"}
      />
    </div>
  );
}

This implementation respects the user's system-level dark mode preference by default while providing a manual toggle for those who want to override it. The prefers-color-scheme media query detects the system preference, and event listeners keep the theme in sync if the user changes their system settings while viewing your content.

User Experience Considerations: Remember theme preferences across sessions by storing them in localStorage. Provide smooth transitions when switching themes to avoid jarring visual changes. Consider the viewing environment—users watching in dark rooms appreciate dark themes, while those in bright environments may prefer light themes regardless of their system preference.

Real-World Theme Examples

Let's explore complete theme implementations for different use cases, demonstrating how theme properties work together to create cohesive designs.

Corporate Professional Theme

A theme suitable for business and enterprise applications with conservative styling and excellent readability.

src/themes/corporate.js
export const corporateTheme = {
  colors: {
    background: "linear-gradient(180deg, #f8fafc, #f1f5f9)",
    controlsBottomBG: "linear-gradient(to top, rgba(241, 245, 249, 0.98), rgba(248, 250, 252, 0.95), transparent)",
    backgroundSecondary: "#ffffff",
    backgroundTertiary: "#f8fafc",
    text: "#0f172a",
    textMuted: "#64748b",
    accent: "#0369a1",
    accentHover: "#0284c7",
    line: "rgba(3, 105, 161, 0.2)",
    controlBg: "rgba(3, 105, 161, 0.08)",
    controlBgHover: "rgba(3, 105, 161, 0.15)",
    controlBorder: "rgba(3, 105, 161, 0.2)",
    panelBg: "#ffffff",
    panelBorder: "rgba(3, 105, 161, 0.2)",
    shadowColor: "rgba(0, 0, 0, 0.1)",
    centerBigBtnStyle: {
      background: "rgba(3, 105, 161, 0.9)",
      color: "#ffffff",
      border: "2px solid rgba(2, 132, 199, 0.5)",
      transition: "all 0.2s ease",
      backdropFilter: "blur(2px)",
      cursor: "pointer",
      bgOnMouseEnter: "rgba(3, 105, 161, 1)",
      borderOnMouseEnter: "rgba(2, 132, 199, 0.7)",
    },
    customCaptionStyle: {
      background: "rgba(15, 23, 42, 0.95)",
      color: "#ffffff",
      padding: "6px 12px",
      borderRadius: "4px",
      fontSize: "clamp(11px, 1.5vw, 15px)",
      fontWeight: 500,
    },
  },
  fonts: {
    primary: "system-ui, -apple-system, sans-serif",
    size: {
      small: "11px",
      medium: "13px",
      large: "15px",
    },
  },
  borderRadius: {
    small: "2px",
    medium: "4px",
    large: "6px",
  },
  spacing: {
    small: "6px",
    medium: "10px",
    large: "14px",
  },
};

This theme uses conservative blue accents, subtle shadows, and system fonts to create a professional appearance appropriate for corporate training videos, investor presentations, or internal communications.

Entertainment Vibrant Theme

A bold, colorful theme perfect for entertainment content, gaming streams, or creative showcases.

src/themes/entertainment.js
export const entertainmentTheme = {
  colors: {
    background: "linear-gradient(135deg, #1e1b4b, #312e81, #1e1b4b)",
    controlsBottomBG: "linear-gradient(to top, rgba(49, 46, 129, 0.95), rgba(30, 27, 75, 0.9), transparent)",
    backgroundSecondary: "#312e81",
    backgroundTertiary: "#3730a3",
    text: "#e0e7ff",
    textMuted: "#a5b4fc",
    accent: "#ec4899",
    accentHover: "#f472b6",
    line: "rgba(236, 72, 153, 0.3)",
    controlBg: "rgba(236, 72, 153, 0.15)",
    controlBgHover: "rgba(236, 72, 153, 0.25)",
    controlBorder: "rgba(236, 72, 153, 0.3)",
    panelBg: "linear-gradient(180deg, #3730a3, #312e81)",
    panelBorder: "rgba(236, 72, 153, 0.3)",
    shadowColor: "rgba(236, 72, 153, 0.3)",
    centerBigBtnStyle: {
      background: "rgba(236, 72, 153, 0.6)",
      color: "#ffffff",
      border: "2px solid rgba(244, 114, 182, 0.5)",
      transition: "all 0.2s ease",
      backdropFilter: "blur(4px)",
      cursor: "pointer",
      bgOnMouseEnter: "rgba(236, 72, 153, 0.9)",
      borderOnMouseEnter: "rgba(244, 114, 182, 0.8)",
    },
    customCaptionStyle: {
      background: "rgba(55, 48, 163, 0.9)",
      color: "#e0e7ff",
      padding: "6px 12px",
      borderRadius: "6px",
      fontSize: "clamp(11px, 1.7vw, 17px)",
      fontWeight: 600,
      backdropFilter: "blur(6px)",
    },
  },
  fonts: {
    primary: "Poppins, system-ui, sans-serif",
    size: {
      small: "12px",
      medium: "14px",
      large: "17px",
    },
  },
  borderRadius: {
    small: "6px",
    medium: "10px",
    large: "16px",
  },
  spacing: {
    small: "8px",
    medium: "14px",
    large: "20px",
  },
};

This theme combines deep purple backgrounds with bright pink accents, generous border radius values, and bold typography to create an energetic, modern appearance perfect for entertainment content.

Brand Consistency:

When creating custom themes, extract your brand colors, fonts, and spacing values into design tokens or CSS variables. This ensures consistency across your entire application, not just the video player. Maintain a style guide documenting your theme choices to ensure consistency across your team.

Troubleshooting Theme Issues

If your custom theme doesn't appear as expected, check these common issues:

Colors Not Applying: Ensure you're passing the theme object to the theme prop, not the style prop. Verify that color values use valid CSS color formats. Check that you're not accidentally overriding theme colors with inline styles elsewhere in your code.

Font Not Loading: Confirm that custom fonts are properly loaded in your application. Web fonts require @font-face declarations or link tags in your HTML. System fonts should include appropriate fallbacks in case the primary font isn't available on the user's system.

Inconsistent Appearance: Make sure you're not mixing theme properties with component-level style overrides. The theme should be your single source of truth for visual styling. If you need component-specific adjustments, consider whether they should be part of the theme instead.

Responsive Issues: Test your theme on various screen sizes. Properties like fontSize that use clamp() ensure responsiveness, but fixed pixel values may not scale well. Use relative units like percentages or viewport units for responsive properties.

Contrast Problems: Use browser developer tools or accessibility checkers to verify color contrast meets WCAG standards. Insufficient contrast makes text hard to read and fails accessibility requirements. Adjust colors until you achieve at least 4.5:1 contrast for normal text.

Next Steps

With your theme configured, explore these related features:

Keyboard Shortcuts: Learn about built-in keyboard controls that enhance the user experience regardless of theme.

Preview on Hover: Discover how the timeline preview feature integrates with your custom theme.

Props: Review all available configuration options to further customize player behavior beyond visual styling.

The theming system gives you complete creative control over the player's appearance while maintaining professional functionality. Whether you're matching a corporate brand, creating an entertainment experience, or building something entirely unique, the comprehensive theme properties support your vision.