Material-UI Theme Customization
January 10, 2024
Sarah Kim
Learn how to create beautiful and consistent designs with Material-UI theme customization and dark mode support.
Material-UI provides a powerful theming system that allows you to customize every aspect of your application's design. This comprehensive guide covers everything from basic customization to advanced theming techniques.
Understanding the Theme Structure
The Material-UI theme is a JavaScript object that defines the design system for your entire application. It consists of several key sections:
Palette
The palette defines colors and color variants used throughout your application:
• Primary colors • Secondary colors • Error, warning, info, success colors • Background and surface colors • Text colors
3const theme = createTheme({
4 palette: {
5 primary: {
6 main: '#1976d2',
7 light: '#42a5f5',
8 dark: '#1565c0',
9 contrastText: '#fff',
10 },
11 secondary: {
12 main: '#dc004e',
13 light: '#f06292',
14 dark: '#c51162',
15 contrastText: '#fff',
16 },
17 },
18});
Typography
Typography settings control font families, sizes, and styles across all text elements:
3const theme = createTheme({
4 typography: {
5 fontFamily: [
6 'Roboto',
7 'Helvetica',
8 'Arial',
9 'sans-serif',
10 ].join(','),
11 h1: {
12 fontSize: '2.5rem',
13 fontWeight: 300,
14 lineHeight: 1.2,
15 },
16 h2: {
17 fontSize: '2rem',
18 fontWeight: 400,
19 lineHeight: 1.3,
20 },
21 body1: {
22 fontSize: '1rem',
23 lineHeight: 1.5,
24 },
25 },
26});
Spacing and Breakpoints
Spacing and breakpoints provide consistent layout patterns and responsive design capabilities:
3const theme = createTheme({
4 spacing: 8, // Base spacing unit
5 breakpoints: {
6 values: {
7 xs: 0,
8 sm: 600,
9 md: 960,
10 lg: 1280,
11 xl: 1920,
12 },
13 },
14});
Creating Custom Themes
Building a custom theme involves careful planning and consideration of your brand identity and user experience goals.
Brand Color Integration
Start by defining your brand colors and mapping them to Material-UI's palette structure:
3import { createTheme } from '@mui/material/styles';
4
5const brandColors = {
6 primary: '#6366f1',
7 secondary: '#f59e0b',
8 accent: '#10b981',
9 neutral: '#6b7280',
10};
11
12const theme = createTheme({
13 palette: {
14 primary: {
15 main: brandColors.primary,
16 },
17 secondary: {
18 main: brandColors.secondary,
19 },
20 success: {
21 main: brandColors.accent,
22 },
23 },
24});
Component Customization
Customize individual components to match your design requirements:
3const theme = createTheme({
4 components: {
5 MuiButton: {
6 styleOverrides: {
7 root: {
8 borderRadius: 8,
9 textTransform: 'none',
10 fontWeight: 600,
11 },
12 contained: {
13 boxShadow: 'none',
14 '&:hover': {
15 boxShadow: '0 4px 8px rgba(0,0,0,0.12)',
16 },
17 },
18 },
19 },
20 MuiCard: {
21 styleOverrides: {
22 root: {
23 borderRadius: 12,
24 boxShadow: '0 2px 8px rgba(0,0,0,0.08)',
25 },
26 },
27 },
28 },
29});
Dark Mode Implementation
Dark mode has become an essential feature for modern applications. Material-UI makes it easy to implement with built-in dark theme support.
Basic Dark Mode Setup
3import { createTheme, ThemeProvider } from '@mui/material/styles';
4import { CssBaseline } from '@mui/material';
5
6const darkTheme = createTheme({
7 palette: {
8 mode: 'dark',
9 primary: {
10 main: '#90caf9',
11 },
12 secondary: {
13 main: '#f48fb1',
14 },
15 background: {
16 default: '#121212',
17 paper: '#1e1e1e',
18 },
19 },
20});
21
22function App() {
23 return (
24 <ThemeProvider theme={darkTheme}>
25 <CssBaseline />
26 <YourApp />
27 </ThemeProvider>
28 );
29}
Dynamic Theme Switching
Implement dynamic theme switching to allow users to toggle between light and dark modes:
3import { useState, createContext, useContext } from 'react';
4import { createTheme, ThemeProvider } from '@mui/material/styles';
5
6const ThemeContext = createContext({
7 darkMode: false,
8 toggleTheme: () => {},
9});
10
11export function CustomThemeProvider({ children }) {
12 const [darkMode, setDarkMode] = useState(false);
13
14 const toggleTheme = () => {
15 setDarkMode(!darkMode);
16 };
17
18 const theme = createTheme({
19 palette: {
20 mode: darkMode ? 'dark' : 'light',
21 primary: {
22 main: darkMode ? '#90caf9' : '#1976d2',
23 },
24 secondary: {
25 main: darkMode ? '#f48fb1' : '#dc004e',
26 },
27 },
28 });
29
30 return (
31 <ThemeContext.Provider value={{ darkMode, toggleTheme }}>
32 <ThemeProvider theme={theme}>
33 {children}
34 </ThemeProvider>
35 </ThemeContext.Provider>
36 );
37}
Persistent Theme Preferences
Save user theme preferences to localStorage
for a better user experience:
3import { useState, useEffect } from 'react';
4
5export function useThemeMode() {
6 const [darkMode, setDarkMode] = useState(() => {
7 if (typeof window !== 'undefined') {
8 const saved = localStorage.getItem('darkMode');
9 return saved ? JSON.parse(saved) : false;
10 }
11 return false;
12 });
13
14 useEffect(() => {
15 localStorage.setItem('darkMode', JSON.stringify(darkMode));
16 }, [darkMode]);
17
18 const toggleTheme = () => {
19 setDarkMode(!darkMode);
20 };
21
22 return { darkMode, toggleTheme };
23}
Advanced Theming Techniques
Custom Color Palettes
Extend the default palette with custom color schemes for specific use cases:
3declare module '@mui/material/styles' {
4 interface Palette {
5 tertiary: Palette['primary'];
6 }
7 interface PaletteOptions {
8 tertiary?: PaletteOptions['primary'];
9 }
10}
11
12const theme = createTheme({
13 palette: {
14 tertiary: {
15 main: '#9c27b0',
16 light: '#ba68c8',
17 dark: '#7b1fa2',
18 contrastText: '#fff',
19 },
20 },
21});
Responsive Typography
Create responsive typography that adapts to different screen sizes:
3const theme = createTheme({
4 typography: {
5 h1: {
6 fontSize: '2.5rem',
7 [theme.breakpoints.down('md')]: {
8 fontSize: '2rem',
9 },
10 [theme.breakpoints.down('sm')]: {
11 fontSize: '1.75rem',
12 },
13 },
14 },
15});
Best Practices
Following theming best practices ensures maintainable and scalable design systems:
Design Token Strategy
• Use consistent naming conventions • Define a clear color hierarchy • Implement proper contrast ratios • Test accessibility across all themes
Performance Considerations
• Avoid unnecessary theme re-creation • Use theme caching where appropriate • Minimize component style overrides • Leverage CSS-in-JS optimization
A well-designed theme system is the foundation of a consistent and professional user interface.
Conclusion
Material-UI's theming system provides incredible flexibility for creating beautiful, consistent, and accessible user interfaces. By following these patterns and best practices, you can build design systems that scale with your application's needs.