跳到内容
+

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,
}));

调色板接口

要将新令牌添加到主题调色板,你需要增强 PaletteOptionsPalette 接口

declare module '@mui/material/styles' {
  interface PaletteOptions {
    gradient: string;
    border: {
      subtle: string;
    };
  }
  interface Palette {
    gradient: string;
    border: {
      subtle: string;
    };
  }
}

下一步

如果你需要支持系统偏好设置和手动选择,请查看高级配置