Introduction to Theming
Theming in React Material is based on Material Design 3's dynamic color system, which allows you to create beautiful, cohesive themes with minimal effort. The library provides a powerful ThemeProvider component that manages color schemes based on a source color or image.
ThemeProvider
The ThemeProvider component is the foundation of theming in React Material. It must wrap your application to provide the theme context to all components.
API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
sourceColor | number | 0xD0BCFF | The main color used to generate the theme palette (in ARGB format) |
sourceImage | string | - | URL to an image from which to extract a source color |
variant | Variant | Variant.TONAL_SPOT | The theme variant style |
contrast | number | 0 | Contrast level from -1 to 1 (-1 for minimum, 1 for maximum) |
root | boolean | false | When true, applies theme to :root (required at the root level) |
maxSnackbars | number | - | Maximum number of snackbars to show simultaneously (only when root={true}) |
Theme Variants
| Variant | Description |
|---|---|
TONAL_SPOT | Low to medium colorfulness with tertiary colors related to the source color |
VIBRANT | High colorfulness with vivid colors |
EXPRESSIVE | High colorfulness with unexpected color combinations |
CONTENT | Places the source color in the primary container |
MONOCHROME | Grayscale theme based on the source color |
Notes
- Must wrap your application to provide theme context to all components
- The
rootprop is required at the root level for proper global styling - When using
sourceImage, the component automatically extracts dominant colors - Only the root-level
ThemeProvidersupports themaxSnackbarsprop
useTheme Hook
A React hook that provides access to the current theme state and actions.
Returns
Usage
Notes
- Must be used within a
ThemeProvidercomponent - Throws an error if used outside of a
ThemeProvider - The
changeThemefunction allows dynamic theme updates at runtime
Using a Source Color
The simplest way to customize your theme is by providing a source color. The source color is used as the base for generating the entire color palette.
Using a Source Image
One of the most powerful features of React Material's theming system is the ability to extract a theme from an image. This is great for creating themes that match your branding or content.
The sourceImage prop accepts a URL to an image. When the image loads, React Material extracts representative colors from the image and generates a harmonious theme based on the dominant color.
The Root Prop
The root prop is a boolean value that determines whether the theme variables are applied to the :root selector. It is required to set root={true} or you can just add prop root on at least one ThemeProvider at the root level of your application to ensure that global styles are applied correctly to elements like body, html, and other global elements.
When root={true}, the theme CSS variables are applied to the :root selector, making them available throughout your entire application, even outside of React components. Without setting this at the root level, some styling might not be applied properly to global elements.
For nested ThemeProviders, you should generally set root={false} (or omit it as it defaults to false) to ensure themes are scoped appropriately:
This approach ensures that:
- Global styles are consistently applied to all elements
- Local theme overrides work as expected
- Your application maintains a coherent design system
Combining Theme Options
You can combine different theme options to create a highly customized theme:
Dynamic Theming
The theme can be changed at runtime using the useTheme hook:
Accessing Theme Values
You can access the current theme values using the useTheme hook:
CSS Variables
React Material automatically generates CSS variables for all theme colors. These variables follow the naming pattern --m3-scheme-{color-name} and contain RGB values (without the rgb() wrapper) that you can use in your CSS:
Available color variables include:
- Primary colors:
primary,on-primary,primary-container,on-primary-container - Secondary colors:
secondary,on-secondary,secondary-container,on-secondary-container - Tertiary colors:
tertiary,on-tertiary,tertiary-container,on-tertiary-container - Surface colors:
surface,on-surface,surface-variant,on-surface-variant - Error colors:
error,on-error,error-container,on-error-container - And many more!
Typography and Fonts
React Material follows Material Design 3's typography system, with Roboto as the default font family. The library provides built-in typography scaling and font management to ensure consistent text rendering across your application.
Default Font (Roboto)
React Material automatically applies Roboto as the default font family for all components. The font is loaded and includes support for multiple weights and styles:
The default typography scale includes:
- Display Large: 57px / 64px line height
- Display Medium: 45px / 52px line height
- Display Small: 36px / 44px line height
- Headline Large: 32px / 40px line height
- Headline Medium: 28px / 36px line height
- Headline Small: 24px / 32px line height
- Title Large: 22px / 28px line height
- Title Medium: 16px / 24px line height
- Title Small: 14px / 20px line height
- Body Large: 16px / 24px line height
- Body Medium: 14px / 20px line height
- Body Small: 12px / 16px line height
- Label Large: 14px / 20px line height
- Label Medium: 12px / 16px line height
- Label Small: 11px / 16px line height
Customizing Fonts with CSS Variables
React Material provides dedicated CSS variables for different typography categories. You can override these variables to use custom fonts for specific text styles:
Loading Custom Fonts
You can load custom fonts using various methods. Here are the most common approaches:
1. Using @font-face
2. Using Google Fonts
3. Using Next.js Font Optimization
Font Loading Best Practices
- Always provide fallback fonts: Include system font fallbacks to ensure text remains readable:
- Use font-display: swap: Ensure text remains visible during font load:
- Preload critical fonts: Use
<link rel="preload">for fonts used above the fold:
- Optimize font loading: Only load the font weights and styles you actually use.
Best Practices
-
Place the ThemeProvider at the root of your application to ensure all components have access to the theme.
-
Use semantic color names instead of hardcoded color values in your components for better theme consistency.
-
Test your themes in both light and dark modes to ensure good contrast and readability.
-
Consider accessibility when choosing source colors and contrast levels.
-
Provide a default theme even if you expect users to customize it later.
-
Use CSS variables for font customization by overriding the
--m3-font-*variables in your:rootselector. -
Always include system font fallbacks to ensure text remains readable even if custom fonts fail to load.
-
Limit font weights to only those you actually use to reduce bundle size and improve loading times.
-
Use
font-display: swapin your@font-facedeclarations for better loading performance. -
Test typography across different devices to ensure readability on various screen sizes and pixel densities.