Material-UI 主题基础 #
什么是主题? #
主题是一组设计规范的集合,包括颜色、排版、间距、形状等。MUI 的主题系统让你可以统一管理应用的视觉风格。
text
┌─────────────────────────────────────────┐
│ MUI 主题结构 │
├─────────────────────────────────────────┤
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐│
│ │ palette │ │typography│ │ spacing ││
│ │ 调色板 │ │ 排版 │ │ 间距 ││
│ └─────────┘ └─────────┘ └─────────┘│
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐│
│ │breakpoints│ │ shape │ │ shadows ││
│ │ 断点 │ │ 形状 │ │ 阴影 ││
│ └─────────┘ └─────────┘ └─────────┘│
│ │
│ ┌─────────┐ ┌─────────┐ │
│ │transitions│ │components│ │
│ │ 过渡 │ │ 组件定制 │ │
│ └─────────┘ └─────────┘ │
│ │
└─────────────────────────────────────────┘
创建主题 #
基础主题 #
jsx
import { createTheme, ThemeProvider } from '@mui/material/styles';
const theme = createTheme();
function App() {
return (
<ThemeProvider theme={theme}>
<YourApp />
</ThemeProvider>
);
}
自定义主题 #
jsx
const theme = createTheme({
palette: {
primary: {
main: '#1976d2',
},
secondary: {
main: '#dc004e',
},
},
typography: {
fontFamily: 'Roboto, Arial, sans-serif',
},
});
调色板(Palette) #
颜色类型 #
MUI 提供多种颜色类型:
jsx
const theme = createTheme({
palette: {
primary: {
main: '#1976d2',
light: '#42a5f5',
dark: '#1565c0',
contrastText: '#fff',
},
secondary: {
main: '#dc004e',
light: '#ff4081',
dark: '#c51162',
contrastText: '#fff',
},
error: {
main: '#f44336',
light: '#e57373',
dark: '#d32f2f',
},
warning: {
main: '#ff9800',
light: '#ffb74d',
dark: '#f57c00',
},
info: {
main: '#2196f3',
light: '#64b5f6',
dark: '#1976d2',
},
success: {
main: '#4caf50',
light: '#81c784',
dark: '#388e3c',
},
},
});
深色模式 #
jsx
const theme = createTheme({
palette: {
mode: 'dark',
primary: {
main: '#90caf9',
},
secondary: {
main: '#f48fb1',
},
background: {
default: '#121212',
paper: '#1e1e1e',
},
},
});
动态切换主题 #
jsx
import { useState } from 'react';
import { createTheme, ThemeProvider, useTheme } from '@mui/material/styles';
import { CssBaseline, Button } from '@mui/material';
function App() {
const [darkMode, setDarkMode] = useState(false);
const theme = createTheme({
palette: {
mode: darkMode ? 'dark' : 'light',
primary: {
main: '#1976d2',
},
},
});
return (
<ThemeProvider theme={theme}>
<CssBaseline />
<Button onClick={() => setDarkMode(!darkMode)}>
切换到{darkMode ? '浅色' : '深色'}模式
</Button>
</ThemeProvider>
);
}
使用内置颜色 #
MUI 提供了 Material Design 的标准颜色:
jsx
import { blue, pink, green } from '@mui/material/colors';
const theme = createTheme({
palette: {
primary: blue,
secondary: pink,
success: green,
},
});
排版(Typography) #
字体家族 #
jsx
const theme = createTheme({
typography: {
fontFamily: [
'-apple-system',
'BlinkMacSystemFont',
'"Segoe UI"',
'Roboto',
'"Helvetica Neue"',
'Arial',
'sans-serif',
].join(','),
},
});
字体变体 #
jsx
const theme = createTheme({
typography: {
h1: {
fontSize: '2.5rem',
fontWeight: 500,
lineHeight: 1.2,
},
h2: {
fontSize: '2rem',
fontWeight: 500,
},
h3: {
fontSize: '1.75rem',
fontWeight: 500,
},
h4: {
fontSize: '1.5rem',
fontWeight: 500,
},
h5: {
fontSize: '1.25rem',
fontWeight: 500,
},
h6: {
fontSize: '1rem',
fontWeight: 500,
},
subtitle1: {
fontSize: '1rem',
fontWeight: 400,
},
subtitle2: {
fontSize: '0.875rem',
fontWeight: 500,
},
body1: {
fontSize: '1rem',
lineHeight: 1.5,
},
body2: {
fontSize: '0.875rem',
lineHeight: 1.5,
},
button: {
textTransform: 'none',
},
caption: {
fontSize: '0.75rem',
},
overline: {
fontSize: '0.75rem',
textTransform: 'uppercase',
},
},
});
使用排版 #
jsx
function TypographyExample() {
return (
<div>
<Typography variant="h1">H1 标题</Typography>
<Typography variant="h2">H2 标题</Typography>
<Typography variant="body1">正文内容</Typography>
<Typography variant="caption">说明文字</Typography>
</div>
);
}
间距(Spacing) #
MUI 使用 8px 为基础单位:
jsx
const theme = createTheme({
spacing: 8,
});
使用间距 #
jsx
<Box sx={{ p: 2 }}>
padding: 16px (8 * 2)
</Box>
<Box sx={{ m: 3 }}>
margin: 24px (8 * 3)
</Box>
<Box sx={{ p: 1.5 }}>
padding: 12px (8 * 1.5)
</Box>
自定义间距函数 #
jsx
const theme = createTheme({
spacing: (factor) => `${0.5 * factor}rem`,
});
断点(Breakpoints) #
默认断点 #
jsx
const theme = createTheme({
breakpoints: {
values: {
xs: 0,
sm: 600,
md: 900,
lg: 1200,
xl: 1536,
},
},
});
使用断点 #
jsx
<Box
sx={{
width: {
xs: '100%',
sm: '80%',
md: '60%',
lg: '50%',
xl: '40%',
},
p: {
xs: 1,
sm: 2,
md: 3,
},
}}
>
响应式 Box
</Box>
useMediaQuery #
jsx
import { useMediaQuery, useTheme } from '@mui/material';
function ResponsiveComponent() {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
const isTablet = useMediaQuery(theme.breakpoints.between('sm', 'md'));
const isDesktop = useMediaQuery(theme.breakpoints.up('md'));
return (
<div>
{isMobile && <MobileView />}
{isTablet && <TabletView />}
{isDesktop && <DesktopView />}
</div>
);
}
形状(Shape) #
圆角 #
jsx
const theme = createTheme({
shape: {
borderRadius: 8,
},
});
使用形状 #
jsx
<Box sx={{ borderRadius: 1 }}>
borderRadius: 8px
</Box>
<Box sx={{ borderRadius: 2 }}>
borderRadius: 16px
</Box>
<Box sx={{ borderRadius: '50%' }}>
圆形
</Box>
阴影(Shadows) #
默认阴影 #
jsx
<Box sx={{ boxShadow: 1 }}>阴影级别 1</Box>
<Box sx={{ boxShadow: 2 }}>阴影级别 2</Box>
<Box sx={{ boxShadow: 3 }}>阴影级别 3</Box>
<Box sx={{ boxShadow: 4 }}>阴影级别 4</Box>
<Box sx={{ boxShadow: 5 }}>阴影级别 5</Box>
自定义阴影 #
jsx
const theme = createTheme({
shadows: [
'none',
'0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)',
],
});
组件定制 #
全局定制 #
jsx
const theme = createTheme({
components: {
MuiButton: {
styleOverrides: {
root: {
borderRadius: 8,
textTransform: 'none',
},
},
},
MuiTextField: {
styleOverrides: {
root: {
marginBottom: 16,
},
},
},
},
});
变体定制 #
jsx
const theme = createTheme({
components: {
MuiButton: {
variants: [
{
props: { variant: 'gradient' },
style: {
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
border: 0,
borderRadius: 3,
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
color: 'white',
},
},
],
},
},
});
<Button variant="gradient">渐变按钮</Button>
默认属性 #
jsx
const theme = createTheme({
components: {
MuiButton: {
defaultProps: {
variant: 'contained',
color: 'primary',
},
},
MuiTextField: {
defaultProps: {
variant: 'outlined',
size: 'small',
},
},
},
});
访问主题 #
useTheme Hook #
jsx
import { useTheme } from '@mui/material/styles';
function MyComponent() {
const theme = useTheme();
return (
<Box sx={{ color: theme.palette.primary.main }}>
主色调文字
</Box>
);
}
styled API #
jsx
import { styled } from '@mui/material/styles';
const MyButton = styled('button')(({ theme }) => ({
padding: theme.spacing(1, 2),
backgroundColor: theme.palette.primary.main,
color: theme.palette.primary.contrastText,
borderRadius: theme.shape.borderRadius,
'&:hover': {
backgroundColor: theme.palette.primary.dark,
},
}));
sx prop #
jsx
<Box
sx={{
p: 2,
bgcolor: 'primary.main',
color: 'primary.contrastText',
borderRadius: 1,
}}
>
使用主题值
</Box>
主题工具函数 #
responsiveFontSizes #
jsx
import { createTheme, responsiveFontSizes } from '@mui/material/styles';
let theme = createTheme();
theme = responsiveFontSizes(theme);
createMuiTheme(已弃用) #
jsx
import { createTheme } from '@mui/material/styles';
const theme = createTheme({
});
完整主题示例 #
jsx
import { createTheme } from '@mui/material/styles';
import { blue, pink } from '@mui/material/colors';
const theme = createTheme({
palette: {
mode: 'light',
primary: {
main: blue[500],
light: blue[300],
dark: blue[700],
},
secondary: {
main: pink[500],
light: pink[300],
dark: pink[700],
},
background: {
default: '#fafafa',
paper: '#ffffff',
},
},
typography: {
fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif',
h1: {
fontSize: '2.5rem',
fontWeight: 500,
},
h2: {
fontSize: '2rem',
fontWeight: 500,
},
h3: {
fontSize: '1.75rem',
fontWeight: 500,
},
button: {
textTransform: 'none',
},
},
spacing: 8,
shape: {
borderRadius: 8,
},
breakpoints: {
values: {
xs: 0,
sm: 600,
md: 900,
lg: 1200,
xl: 1536,
},
},
components: {
MuiButton: {
styleOverrides: {
root: {
borderRadius: 8,
},
},
},
MuiCard: {
styleOverrides: {
root: {
boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
},
},
},
},
});
export default theme;
下一步 #
现在你已经掌握了主题基础,继续学习 布局组件,深入了解 MUI 的布局系统!
最后更新:2026-03-28