跳到主要內容
+

CSS 主題變數 - 設定

Material UI 中設定 CSS 主題變數的指南。

客製化變數前綴

若要變更預設的變數前綴 (--mui),請提供字串給 cssVarPrefix 屬性,如下所示

createTheme({ cssVariables: { cssVarPrefix: 'any' } });

// generated stylesheet:
// --any-palette-primary-main: ...;

若要移除前綴,請使用空字串作為值

createTheme({ cssVariables: { cssVarPrefix: '' } });

// generated stylesheet:
// --palette-primary-main: ...;

手動切換深色模式

若要手動切換模式,請使用下列其中一個選擇器設定 colorSchemeSelector

createTheme({
  colorSchemes: { light: true, dark: true },
  cssVariables: {
    colorSchemeSelector: 'class'
  }
});

// CSS Result
.light { ... }
.dark { ... }

然後,使用 useColorScheme Hook 在模式之間切換

import { useColorScheme } from '@mui/material/styles';

function ModeSwitcher() {
  const { mode, setMode } = useColorScheme();

  if (!mode) {
    return null;
  }

  return (
    <select
      value={mode}
      onChange={(event) => {
        setMode(event.target.value);
        // For TypeScript, cast `event.target.value as 'light' | 'dark' | 'system'`:
      }}
    >
      <option value="system">System</option>
      <option value="light">Light</option>
      <option value="dark">Dark</option>
    </select>
  );
}

判斷系統模式

若要判斷系統模式是 lightdark,請使用 systemMode 屬性

const { mode, systemMode } = useColorScheme();

console.log(mode); // 'system'
console.log(systemMode); // 'light' | 'dark'

但是,如果模式不是 system,則 systemMode 將會是 undefined

const { mode, systemMode } = useColorScheme();

console.log(mode); // 'light' | 'dark'
console.log(systemMode); // undefined

防止 SSR 閃爍

對於 SSR (伺服器端渲染) 應用程式,Material UI 無法在伺服器上偵測使用者選取的模式,導致在用戶端水合階段期間螢幕從亮色閃爍到深色。

為了防止這個問題,您需要確保您的程式碼庫中沒有使用 theme.palette.mode === 'dark'

如果您有這樣的條件,請使用 theme.applyStyles() 函數 取代它

 import Card from '@mui/material/Card';

 function App() {
   return (
     <Card
-      sx={(theme) => ({
-        backgroundColor: theme.palette.mode === 'dark' ? '#000' : '#fff',
-        '&:hover': {
-          backgroundColor: theme.palette.mode === 'dark' ? '#333' : '#f5f5f5',
-        },
-      })}
+      sx={[
+        {
+          backgroundColor: '#fff',
+          '&:hover': {
+            backgroundColor: '#f5f5f5',
+          },
+        },
+        (theme) =>
+          theme.applyStyles('dark', {
+            backgroundColor: '#000',
+            '&:hover': {
+              backgroundColor: '#333',
+            },
+          }),
+      ]}
     />
   );
 }

接下來,如果您有不是 media 的自訂選擇器,請根據您使用的框架新增 InitColorSchemeScript 元件

Next.js App Router

將下列程式碼新增至 根版面配置 檔案

app/layout.js
import InitColorSchemeScript from '@mui/material/InitColorSchemeScript';

export default function RootLayout(props) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body>
        {/* must come before the <main> element */}
        <InitColorSchemeScript attribute="class" />
        <main>{children}</main>
      </body>
    </html>
  );
}

Next.js Pages Router

將下列程式碼新增至自訂的 pages/_document.js 檔案

pages/_document.js
import Document, { Html, Head, Main, NextScript } from 'next/document';
import InitColorSchemeScript from '@mui/material/InitColorSchemeScript';

export default class MyDocument extends Document {
  render() {
    return (
      <Html>
        <Head>...</Head>
        <body>
          {/* must come before the <Main> element */}
          <InitColorSchemeScript attribute="class" />
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

Gatsby

將指令碼放置在您的 gatsby-ssr.js 檔案中

import * as React from 'react';
import InitColorSchemeScript from '@mui/material/InitColorSchemeScript';

export function onRenderBody({ setPreBodyComponents }) {
  setPreBodyComponents([<InitColorSchemeScript attribute="class" />]);
}

強制使用特定色彩配置

若要為應用程式的某些部分強制使用特定色彩配置,請將選擇器直接設定為元件或 HTML 元素。

在以下範例中,div 內的所有元件都會永遠是深色

// if the selector is '.mode-%s'
<div className=".mode-dark">
  <Paper sx={{ p: 2 }}>
    <TextField label="Email" type="email" margin="normal" />
    <TextField label="Password" type="password" margin="normal" />
    <Button>Sign in</Button>
  </Paper>
  {/* other components */}
</div>

停用 CSS 色彩配置

預設情況下,createTheme() 會根據 Palette 模式附加 CSS color-scheme 屬性。您可以透過將 disableCssColorScheme 設定為 true 來停用此功能

createTheme({
  cssVariables: { disableCssColorScheme: true },
});

產生的 CSS 將不會包含 color-scheme 屬性

 @media (prefers-color-scheme: dark) {
   :root {
-    color-scheme: dark;
     --mui-palette-primary-main: #90caf9;
     ...
   }
 }

色彩配置之間即時轉換

若要在模式之間切換時停用 CSS 轉場效果,請套用 disableTransitionOnChange 屬性

<ThemeProvider disableTransitionOnChange />

強制在模式之間重新計算主題

預設情況下,當主題中設定 cssVariables: true 時,在亮色和深色模式之間切換時,ThemeProvider 不會重新渲染。

如果您想要退出此行為,請在 ThemeProvider 中使用 forceThemeRerender 屬性

<ThemeProvider forceThemeRerender />