跳到主要内容
+

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

确定系统模式

要确定系统模式是 light 还是 dark,请使用 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 无法在服务器上检测到用户选择的模式,从而导致屏幕在客户端 hydration 阶段从亮到暗闪烁。

要防止此问题,您需要确保代码库中没有使用 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() 基于调色板模式附加 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 />