CSS 主题变量 - 用法
了解如何采用 CSS 主题变量。
开始使用
要使用 CSS 主题变量,请创建一个 cssVariables: true
的主题,并使用 ThemeProvider
包裹你的应用。
渲染后,你将在 HTML 文档的 :root
样式表中看到 CSS 变量。默认情况下,这些变量会被扁平化并以 --mui
为前缀
import { ThemeProvider, createTheme } from '@mui/material/styles';
const theme = createTheme({ cssVariables: true });
function App() {
return <ThemeProvider theme={theme}>{/* ...your app */}</ThemeProvider>;
}
亮色和暗色模式
当内置的暗色配色方案和 cssVariables
启用时,亮色和暗色 CSS 变量都会使用默认的 CSS 媒体查询 prefers-color-scheme
方法生成。
此方法适用于服务端渲染,无需额外配置。但是,用户将无法在模式之间切换,因为样式是基于浏览器媒体查询的。
如果你希望能够手动切换模式,请参阅手动切换暗黑模式指南。
应用暗色样式
要自定义暗黑模式的样式,请使用theme.applyStyles()
函数。
下面的示例展示了如何为暗黑模式自定义 Card 组件
import Card from '@mui/material/Card';
<Card
sx={[
(theme) => ({
backgroundColor: theme.vars.palette.background.default,
}),
(theme) =>
theme.applyStyles('dark', {
backgroundColor: theme.vars.palette.grey[900],
}),
]}
/>;
使用主题变量
当 CSS 变量功能启用时,vars
节点会添加到主题中。这个 vars
对象镜像了可序列化主题的结构,每个值都对应一个 CSS 变量。
theme.vars
(推荐):一个引用 CSS 主题变量的对象。const Button = styled('button')(({ theme }) => ({ backgroundColor: theme.vars.palette.primary.main, // var(--mui-palette-primary-main) color: theme.vars.palette.primary.contrastText, // var(--mui-palette-primary-contrastText) }));
对于 TypeScript,类型定义默认不启用。请按照TypeScript 设置启用类型定义。
原生 CSS:如果你无法访问主题对象,例如在纯 CSS 文件中,你可以直接使用
var()
/* external-scope.css */ .external-section { background-color: var(--mui-palette-grey-50); }
颜色通道令牌
启用 cssVariables
会自动生成通道令牌,用于创建半透明颜色。这些令牌由不带 alpha 分量的颜色空间通道组成,通道之间用空格分隔。
颜色会附加 Channel
后缀——例如
const theme = createTheme({ cssVariables: true });
console.log(theme.palette.primary.mainChannel); // '25 118 210'
// This token is generated from `theme.colorSchemes.light.palette.primary.main`.
你可以像这样使用通道令牌来创建半透明颜色
const theme = createTheme({
cssVariables: true,
components: {
MuiChip: {
styleOverrides: {
root: ({ theme }) => ({
variants: [
{
props: { variant: 'outlined', color: 'primary' },
style: {
backgroundColor: `rgba(${theme.vars.palette.primary.mainChannel} / 0.12)`,
},
},
],
}),
},
},
},
});
添加新的主题令牌
你可以将其他键值对添加到主题输入中,这些键值对将作为 CSS 主题变量的一部分生成
const theme = createTheme({
cssVariables: true,
colorSchemes: {
light: {
palette: {
// The best part is that you can refer to the variables wherever you like 🤩
gradient:
'linear-gradient(to left, var(--mui-palette-primary-main), var(--mui-palette-primary-dark))',
border: {
subtle: 'var(--mui-palette-neutral-200)',
},
},
},
dark: {
palette: {
gradient:
'linear-gradient(to left, var(--mui-palette-primary-light), var(--mui-palette-primary-main))',
border: {
subtle: 'var(--mui-palette-neutral-600)',
},
},
},
},
});
function App() {
return <ThemeProvider theme={theme}>...</ThemeProvider>;
}
然后,你可以从 theme.vars
对象访问这些变量
const Divider = styled('hr')(({ theme }) => ({
height: 1,
border: '1px solid',
borderColor: theme.vars.palette.border.subtle,
backgroundColor: theme.vars.palette.gradient,
}));
或者使用 var()
直接引用 CSS 变量
/* global.css */
.external-section {
background-color: var(--mui-palette-gradient);
}
对于 TypeScript,你需要增强调色板接口。
TypeScript
主题变量类型默认不启用。你需要导入模块增强来启用类型定义
// The import can be in any file that is included in your `tsconfig.json`
import type {} from '@mui/material/themeCssVarsAugmentation';
import { styled } from '@mui/material/styles';
const StyledComponent = styled('button')(({ theme }) => ({
// ✅ typed-safe
color: theme.vars.palette.primary.main,
}));
调色板接口
要将新令牌添加到主题调色板,你需要增强 PaletteOptions
和 Palette
接口
declare module '@mui/material/styles' {
interface PaletteOptions {
gradient: string;
border: {
subtle: string;
};
}
interface Palette {
gradient: string;
border: {
subtle: string;
};
}
}
下一步
如果你需要支持系统偏好设置和手动选择,请查看高级配置