跳到內容
+

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

下一步

如果您需要支援系統偏好設定和手動選擇,請查看進階配置