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 無法在伺服器上偵測使用者選取的模式,導致在用戶端水合階段期間螢幕從亮色閃爍到深色。
為了防止這個問題,您需要確保您的程式碼庫中沒有使用 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
將下列程式碼新增至 根版面配置 檔案
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
檔案
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 />