使用 CssVarsProvider 來取得 MaterialUI 樣式的 CSS 變數
總結
在一些情況下可能會選擇透過透過 CSS 變數 var()
來指定樣式,而 MaterialUI 的 CssVarsProvider
元件可讓開發者取得 CSS 變數版本的 MaterialUI 樣式設定(theme object),且可搭配 useColorScheme
來指定取得 light 或 dark 模式的樣式。
版本與環境
@mui/material: 5.11.7
筆記
情境範例
比如我想直接借用 MaterialUI 預設的 dark mode 色票,且想透過 CSS Module 集中管理樣式資訊,此時即可直接透過 var()
將 MaterialUI 設定好的顏色變數傳入 index.module.css
中:
CssVarsProvider
透過 import { Experimental_CssVarsProvider as CssVarsProvider } from '@mui/material/styles';
來匯入 CssVarsProvider
元件,使用方式基本如下:
import * as React from 'react';
import { render } from 'react-dom';
import { Experimental_CssVarsProvider as CssVarsProvider } from '@mui/material/styles';
import CssBaseline from '@mui/material/CssBaseline';
import ToggleButton from './ToggleButton';
import scopedStyle from './index.module.css';
import './styles.css';
function App() {
/* Main */
return (
<CssVarsProvider>
<CssBaseline />
<div className="App">
<ToggleButton />
<ul>
<li className={scopedStyle.muiPrimaryMain}>
--mui-palette-primary-main
</li>
<li className={scopedStyle.muiSecondaryMain}>
--mui-palette-secondary-main
</li>
<li className={scopedStyle.muiErrorMain}>--mui-palette-error-main</li>
<li className={scopedStyle.muiWarningMain}>
--mui-palette-warning-main
</li>
<li className={scopedStyle.muiInfoMain}>--mui-palette-info-main</li>
<li className={scopedStyle.muiSuccessMain}>
--mui-palette-success-main
</li>
</ul>
</div>
</CssVarsProvider>
);
}
const rootElement = document.getElementById('root');
render(<App />, rootElement);
CssVarsProvider
會把 MaterialUI 的樣式設定透過 css 變數的形式注入到 React app 中,預設的樣式選取器是 :root
,可以透過 props.colorSchemeSelector
來執行客製。下方範例即是將 CSS 變數群注入到 #root
選取器之下:
<CssVarsProvider colorSchemeSelector="#root">{/* 略 */}</CssVarsProvider>
如果想要預設載入 dark mode 的 MaterialUI 樣式,可透過 props.defaultMode
來設定:
<CssVarsProvider defaultMode="dark">{/* 略 */}</CssVarsProvider>
其他可使用的元件 props
可參考 /material-ui/packages/mui-system/src/cssVars/createCssVarsProvider.d.ts
。
注意事項:使用 CssVarsProvider
的話,就不需要再為 app 加上 import { ThemeProvider } from '@mui/material/styles';
了。從原始碼的最終回傳結果可看到 ThemeProvider
是一起被打包丟出來的,不需要再手動引用。
// 套件檔案路徑: /material-ui/packages/mui-system/src/cssVars/createCssVarsProvider.js
// 部分內容略,僅貼出回傳相關段落
const element = (
<React.Fragment>
{shouldGenerateStyleSheet && (
<React.Fragment>
<GlobalStyles styles={{ [colorSchemeSelector]: rootCss }} />
<GlobalStyles styles={defaultColorSchemeStyleSheet} />
<GlobalStyles styles={otherColorSchemesStyleSheet} />
</React.Fragment>
)}
<ThemeProvider theme={resolveTheme ? resolveTheme(theme) : theme}>
{children}
</ThemeProvider>
</React.Fragment>
);
if (nested) {
return element;
}
return (
<ColorSchemeContext.Provider value={contextValue}>
{element}
</ColorSchemeContext.Provider>
);
useColorScheme
搭配 import { useColorScheme } from '@mui/material/styles';
即可取得當下的 MaterialUI mode 資訊。也可透過 setMode
直接更新 mode 設定:
import React from 'react';
import { useColorScheme } from '@mui/material/styles';
import Button from '@mui/material/Button';
function ToggleButton() {
const { mode, setMode } = useColorScheme();
const updateMuiMode = () => {
if (mode === 'light') {
setMode('dark');
} else {
setMode('light');
}
};
return (
<Button onClick={updateMuiMode} variant="contained" disableElevation>
current mode: {mode}
</Button>
);
}
export default ToggleButton;
而所有的 MaterialUI CSS 變數內容都可以透過瀏覽器的開發者工具來查詢: