跳至內容
返回部落格

Material UI v6 現已發布 🎉

Aarón García

@aarongarciah

Brijesh Bittu

@brijeshb42

Diego Andai

@DiegoAndai

Marija Najdova

@mnajdova

Romain Gregoire

@romgrk

Sam Sycamore

@samuelsycamore

Siriwat Kunaporn

@siriwatknp

Victor Zanivan Monteiro

@zanivan
+

Material UI v6 現在已穩定發布 — 正好趕上慶祝 我們首次提交 10 週年!它帶來了新功能、改進和用於靜態 CSS 提取的實驗性整合。

目錄

新功能

CSS 主題變數

CSS 變數已成為網路產業標準。Material UI v6 引入了一個新的 cssVariables 標記,可從可序列化的主題值(例如調色盤、間距和排版)產生 CSS 變數。

const theme = createTheme({ cssVariables: true, ... });
淺色深色字型覆蓋陰影間距形狀z 索引
--mui-common-black--mui-common-black--mui-font-h1--mui-overlays-0--mui-shadows-0--mui-spacing--mui-shape-borderRadius--mui-zIndex-mobileStepper
--mui-common-white--mui-common-white--mui-font-h2--mui-overlays-1--mui-shadows-1--mui-zIndex-fab
--mui-common-background--mui-common-background--mui-font-h3--mui-overlays-2--mui-shadows-2--mui-zIndex-speedDial
--mui-common-onBackground--mui-common-onBackground--mui-font-h4--mui-overlays-3--mui-shadows-3--mui-zIndex-appBar
--mui-common-backgroundChannel--mui-common-backgroundChannel--mui-font-h5--mui-overlays-4--mui-shadows-4--mui-zIndex-drawer
--mui-common-onBackgroundChannel--mui-common-onBackgroundChannel--mui-font-h6--mui-overlays-5--mui-shadows-5--mui-zIndex-modal
--mui-primary-main--mui-primary-main--mui-font-subtitle1--mui-overlays-6--mui-shadows-6--mui-zIndex-snackbar
--mui-primary-light--mui-primary-light--mui-font-subtitle2--mui-overlays-7--mui-shadows-7--mui-zIndex-tooltip
--mui-primary-dark--mui-primary-dark--mui-font-body1--mui-overlays-8--mui-shadows-8
--mui-primary-contrastText--mui-primary-contrastText--mui-font-body2--mui-overlays-9--mui-shadows-9
--mui-primary-mainChannel--mui-primary-mainChannel--mui-font-button--mui-overlays-10--mui-shadows-10
--mui-primary-lightChannel--mui-primary-lightChannel--mui-font-caption--mui-overlays-11--mui-shadows-11
--mui-primary-darkChannel--mui-primary-darkChannel--mui-font-overline--mui-overlays-12--mui-shadows-12
--mui-primary-contrastTextChannel--mui-primary-contrastTextChannel--mui-font-inherit--mui-overlays-13--mui-shadows-13
--mui-secondary-main--mui-secondary-main--mui-overlays-14--mui-shadows-14
--mui-secondary-light--mui-secondary-light--mui-overlays-15--mui-shadows-15
--mui-secondary-dark--mui-secondary-dark--mui-overlays-16--mui-shadows-16
--mui-secondary-contrastText--mui-secondary-contrastText--mui-overlays-17--mui-shadows-17
--mui-secondary-mainChannel--mui-secondary-mainChannel--mui-overlays-18--mui-shadows-18
--mui-secondary-lightChannel--mui-secondary-lightChannel--mui-overlays-19--mui-shadows-19
--mui-secondary-darkChannel--mui-secondary-darkChannel--mui-overlays-20--mui-shadows-20
--mui-secondary-contrastTextChannel--mui-secondary-contrastTextChannel--mui-overlays-21--mui-shadows-21
--mui-error-main--mui-error-main--mui-overlays-22--mui-shadows-22
--mui-error-light--mui-error-light--mui-overlays-23--mui-shadows-23
--mui-error-dark--mui-error-dark--mui-overlays-24--mui-shadows-24
--mui-error-contrastText--mui-error-contrastText
--mui-error-mainChannel--mui-error-mainChannel
--mui-error-lightChannel--mui-error-lightChannel
--mui-error-darkChannel--mui-error-darkChannel
--mui-error-contrastTextChannel--mui-error-contrastTextChannel
--mui-warning-main--mui-warning-main
--mui-warning-light--mui-warning-light
--mui-warning-dark--mui-warning-dark
--mui-warning-contrastText--mui-warning-contrastText
--mui-warning-mainChannel--mui-warning-mainChannel
--mui-warning-lightChannel--mui-warning-lightChannel
--mui-warning-darkChannel--mui-warning-darkChannel
--mui-warning-contrastTextChannel--mui-warning-contrastTextChannel
--mui-info-main--mui-info-main
--mui-info-light--mui-info-light
--mui-info-dark--mui-info-dark
--mui-info-contrastText--mui-info-contrastText
--mui-info-mainChannel--mui-info-mainChannel
--mui-info-lightChannel--mui-info-lightChannel
--mui-info-darkChannel--mui-info-darkChannel
--mui-info-contrastTextChannel--mui-info-contrastTextChannel
--mui-success-main--mui-success-main
--mui-success-light--mui-success-light
--mui-success-dark--mui-success-dark
--mui-success-contrastText--mui-success-contrastText
--mui-success-mainChannel--mui-success-mainChannel
--mui-success-lightChannel--mui-success-lightChannel
--mui-success-darkChannel--mui-success-darkChannel
--mui-success-contrastTextChannel--mui-success-contrastTextChannel
--mui-grey-50--mui-grey-50
--mui-grey-100--mui-grey-100
--mui-grey-200--mui-grey-200
--mui-grey-300--mui-grey-300
--mui-grey-400--mui-grey-400
--mui-grey-500--mui-grey-500
--mui-grey-600--mui-grey-600
--mui-grey-700--mui-grey-700
--mui-grey-800--mui-grey-800
--mui-grey-900--mui-grey-900
--mui-grey-A100--mui-grey-A100
--mui-grey-A200--mui-grey-A200
--mui-grey-A400--mui-grey-A400
--mui-grey-A700--mui-grey-A700
--mui-text-primary--mui-text-primary
--mui-text-secondary--mui-text-secondary
--mui-text-disabled--mui-text-disabled
--mui-text-icon--mui-text-icon
--mui-text-primaryChannel--mui-text-primaryChannel
--mui-text-secondaryChannel--mui-text-secondaryChannel
--mui-divider--mui-divider
--mui-background-paper--mui-background-paper
--mui-background-default--mui-background-default
--mui-background-defaultChannel--mui-background-defaultChannel
--mui-background-paperChannel--mui-background-paperChannel
--mui-action-active--mui-action-active
--mui-action-hover--mui-action-hover
--mui-action-hoverOpacity--mui-action-hoverOpacity
--mui-action-selected--mui-action-selected
--mui-action-selectedOpacity--mui-action-selectedOpacity
--mui-action-disabled--mui-action-disabled
--mui-action-disabledBackground--mui-action-disabledBackground
--mui-action-disabledOpacity--mui-action-disabledOpacity
--mui-action-focus--mui-action-focus
--mui-action-focusOpacity--mui-action-focusOpacity
--mui-action-activatedOpacity--mui-action-activatedOpacity
--mui-action-activeChannel--mui-action-activeChannel
--mui-action-selectedChannel--mui-action-selectedChannel
--mui-Alert-errorColor--mui-Alert-errorColor
--mui-Alert-infoColor--mui-Alert-infoColor
--mui-Alert-successColor--mui-Alert-successColor
--mui-Alert-warningColor--mui-Alert-warningColor
--mui-Alert-errorFilledBg--mui-Alert-errorFilledBg
--mui-Alert-infoFilledBg--mui-Alert-infoFilledBg
--mui-Alert-successFilledBg--mui-Alert-successFilledBg
--mui-Alert-warningFilledBg--mui-Alert-warningFilledBg
--mui-Alert-errorFilledColor--mui-Alert-errorFilledColor
--mui-Alert-infoFilledColor--mui-Alert-infoFilledColor
--mui-Alert-successFilledColor--mui-Alert-successFilledColor
--mui-Alert-warningFilledColor--mui-Alert-warningFilledColor
--mui-Alert-errorStandardBg--mui-Alert-errorStandardBg
--mui-Alert-infoStandardBg--mui-Alert-infoStandardBg
--mui-Alert-successStandardBg--mui-Alert-successStandardBg
--mui-Alert-warningStandardBg--mui-Alert-warningStandardBg
--mui-Alert-errorIconColor--mui-Alert-errorIconColor
--mui-Alert-infoIconColor--mui-Alert-infoIconColor
--mui-Alert-successIconColor--mui-Alert-successIconColor
--mui-Alert-warningIconColor--mui-Alert-warningIconColor
--mui-AppBar-defaultBg--mui-AppBar-defaultBg
--mui-AppBar-darkBg--mui-AppBar-darkBg
--mui-AppBar-darkColor--mui-AppBar-darkColor
--mui-Avatar-defaultBg--mui-Avatar-defaultBg
--mui-Button-inheritContainedBg--mui-Button-inheritContainedBg
--mui-Button-inheritContainedHoverBg--mui-Button-inheritContainedHoverBg
--mui-Chip-defaultBorder--mui-Chip-defaultBorder
--mui-Chip-defaultAvatarColor--mui-Chip-defaultAvatarColor
--mui-Chip-defaultIconColor--mui-Chip-defaultIconColor
--mui-FilledInput-bg--mui-FilledInput-bg
--mui-FilledInput-hoverBg--mui-FilledInput-hoverBg
--mui-FilledInput-disabledBg--mui-FilledInput-disabledBg
--mui-LinearProgress-primaryBg--mui-LinearProgress-primaryBg
--mui-LinearProgress-secondaryBg--mui-LinearProgress-secondaryBg
--mui-LinearProgress-errorBg--mui-LinearProgress-errorBg
--mui-LinearProgress-infoBg--mui-LinearProgress-infoBg
--mui-LinearProgress-successBg--mui-LinearProgress-successBg
--mui-LinearProgress-warningBg--mui-LinearProgress-warningBg
--mui-Skeleton-bg--mui-Skeleton-bg
--mui-Slider-primaryTrack--mui-Slider-primaryTrack
--mui-Slider-secondaryTrack--mui-Slider-secondaryTrack
--mui-Slider-errorTrack--mui-Slider-errorTrack
--mui-Slider-infoTrack--mui-Slider-infoTrack
--mui-Slider-successTrack--mui-Slider-successTrack
--mui-Slider-warningTrack--mui-Slider-warningTrack
--mui-SnackbarContent-bg--mui-SnackbarContent-bg
--mui-SnackbarContent-color--mui-SnackbarContent-color
--mui-SpeedDialAction-fabHoverBg--mui-SpeedDialAction-fabHoverBg
--mui-StepConnector-border--mui-StepConnector-border
--mui-StepContent-border--mui-StepContent-border
--mui-Switch-defaultColor--mui-Switch-defaultColor
--mui-Switch-defaultDisabledColor--mui-Switch-defaultDisabledColor
--mui-Switch-primaryDisabledColor--mui-Switch-primaryDisabledColor
--mui-Switch-secondaryDisabledColor--mui-Switch-secondaryDisabledColor
--mui-Switch-errorDisabledColor--mui-Switch-errorDisabledColor
--mui-Switch-infoDisabledColor--mui-Switch-infoDisabledColor
--mui-Switch-successDisabledColor--mui-Switch-successDisabledColor
--mui-Switch-warningDisabledColor--mui-Switch-warningDisabledColor
--mui-TableCell-border--mui-TableCell-border
--mui-Tooltip-bg--mui-Tooltip-bg
--mui-dividerChannel--mui-dividerChannel

啟用標flag後,您可以從 theme.vars 物件中存取變數,其結構與主題相同。

const CustomComponent = styled('div')(({ theme }) => ({
  backgroundColor: theme.vars.palette.background.default,
  color: theme.vars.palette.text.primary,
}));

優點

  • 改善開發者體驗——您可以在瀏覽器的開發者工具中看到值的來源。

  • 使其有可能解決惡名昭彰的 黑暗模式 SSR 閃爍問題

  • CSS 變數為整合開啟了許多扇門——例如,您可以在純 CSS 檔案中使用 Material UI 主題。

    styles.css
    .custom-card {
      background-color: var(--mui-palette-background-default);
      color: var(--mui-palette-text-primary);
      padding: var(--mui-spacing-2);
      font: var(--mui-font-body1);
    }
    

色彩配置

在 v6 之前,如果您想要支援淺色和深色模式,您必須建立兩個獨立的主題並處理在模式之間切換的邏輯。這可能很複雜且容易出錯。

Material UI v6 引入了新的 colorSchemes 節點來簡化此過程:只需一行程式碼,您的應用程式即可立即支援淺色和深色模式。

const theme = createTheme({ colorSchemes: { dark: true } });
// light is generated by default.

function App() {
  return <ThemeProvider theme={theme}>...</ThemeProvider>;
}

colorSchemes 節點使 Material UI 能夠開箱即用地支援以下功能

  • 系統偏好偵測
  • 使用 disableTransitionOnChange 屬性實現模式之間的即時轉換
  • 透過本機儲存持久化使用者偏好設定
  • 跨瀏覽器標籤頁自動同步選定的模式

用於切換模式的 Hook

新的 useColorScheme Hook 讓您可以在應用程式中讀取和更新模式。

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

function ModeSwitcher() {
  const { mode, setMode } = useColorScheme();
  if (!mode) return null;
  return (
    <select onChange={(event) => setMode(event.target.value)}>
      <option value="system">System</option>
      <option value="light">Light</option>
      <option value="dark">Dark</option>
    </select>
  );
}

CSS 媒體查詢 prefers-color-scheme

CSS 變數色彩配置 啟用時,Material UI 使用 prefers-color-scheme 媒體查詢作為產生 CSS 變數的預設方法。

import { createTheme, ThemeProvider } from '@mui/material/styles';

const theme = createTheme({
  cssVariables: true,
  colorSchemes: { dark: true },
});

function App() {
  return <ThemeProvider theme={theme}>...</ThemeProvider>;
}

容器查詢

Material UI v6 引入了基於現有 theme.breakpoints API 的 容器查詢 工具。

此功能讓您可以根據父容器的寬度而不是視窗寬度定義樣式。

const Component = styled('div')(({ theme }) => ({
  display: 'flex',
  flexDirection: 'column',
  gap: theme.spacing(2),
  [theme.containerQueries.up('sm')]: {
    flexDirection: 'row',
  },
  [theme.containerQueries('sidebar').up('400px')]: {
    // @container sidebar (min-width: 400px)
    flexDirection: 'row',
  },
}));

它也適用於 sx 屬性

<Card
  sx={{
    '@sm': {
      flexDirection: 'row',
    },
    '@400/sidebar': {
      flexDirection: 'row',
    },
  }}
/>

應用樣式的新方法

新增了新的 API theme.applyStyles(),用於建立特定的模式樣式。它旨在取代 theme.palette.mode === 'dark' 條件,以修復與 CSS 主題變數功能結合使用時的 SSR 閃爍問題。

const StyledInput = styled(InputBase)(({ theme }) => ({
  padding: 10,
  width: '100%',
  borderBottom: '1px solid #eaecef',
  ...theme.applyStyles('dark', {
    borderBottom: '1px solid #30363d',
  }),
  '& input': {
    borderRadius: 4,
    backgroundColor: '#fff',
    ...theme.applyStyles('dark', {
      backgroundColor: '#0d1117',
    }),
  },
}));

改進

最佳化執行階段效能

已進行多項最佳化,以改善 Material UI v6 的執行階段效能。

這僅僅是我們效能改進的開始。我們的管道中還有更多最佳化,敬請期待後續的 v6.x 更新和基準測試結果。

改版後的免費範本

探索全新且經過改進的免費 Material UI 範本,以查看所有新 v6 功能的實際應用。我們已全面改版範本,以示範元件的一些常見實際使用案例,並為您的下一個專案提供完美的起點。

自訂樣式

新的範本可以在預設 Material Design 和整個套件共用的完全自訂主題之間切換,因此您可以深入研究元件自訂的最佳方法——或者只是抓取您最喜歡的部分並從那裡開始建構。

穩定的 Grid v2

Grid v2 元件已穩定,現在使用 CSS gap 屬性來建立網格項目之間的空間。與先前使用邊距和內距來建立空間的版本相比,這是一個巨大的改進。

響應式配置已整合到 sizeoffset 屬性中,以保持一致性。

import Grid from '@mui/material/Grid2';

<Grid container>
  <Grid size={{ xs: 6, sm: 4, lg: 3 }} />
  <Grid size={{ xs: 6, sm: 4, lg: 3 }} />
  <Grid size={{ xs: 6, sm: 4, lg: 3 }} />
</Grid>;

縮減套件大小

為了與 React 19 移除 UMD 建置版本保持一致,Material UI 也移除了其 UMD 套件。這使得 @mui/material 套件大小縮減了 2.5MB,或 v5 中總大小的 25%。請參閱 Package Phobia 以取得更多詳細資訊。除了 UMD 之外,我們建議使用基於 ESM 的 CDN,例如 esm.sh。如需其他安裝方法,請參閱CDN 文件

透過 Pigment CSS 進行實驗性 CSS 提取

Material UI v5 使用 Emotion 作為其預設樣式解決方案。由於它是一個執行階段 CSS-in-JS 函式庫,Emotion 迫使我們在效能和套件大小之間做出妥協。

Material UI v6 引入了與 Pigment CSS 的選擇性整合,Pigment CSS 是我們新的零執行階段樣式函式庫,它消除了執行階段開銷,同時保留了您已經熟悉和喜愛的 API 設計模式。

React 伺服器元件

與 Pigment CSS 整合後,Material UI v6 提供了一組獨立的版面配置元件——Grid、Container 和 Stack——它們與 React 伺服器元件相容。

import Grid from '@mui/material-pigment-css/Grid';
import Container from '@mui/material-pigment-css/Container';
import Stack from '@mui/material-pigment-css/Stack';

內建 sx 屬性支援

透過 Pigment CSS 整合,所有 JSX 元素都開箱即用地支援 sx 屬性。這表示您不再需要使用 Box 或 Stack 之類的包裝器來混亂 DOM,以便將自訂樣式應用於 <div> 或任何其他具有 sx 屬性的元素。

-import Box from '@mui/material/Box';

-<Box component="img" sx={{ padding: 2 }} />
+<img sx={{ padding: 2 }} />

React 19 支援

Material UI v6 已為 React 19 做好準備。我們一直在使用最新的 React 19 RC 版本測試 Material UI,以確保在 React 19 穩定版本發佈後具有相容性。

我們也正在努力將 React 19 支援向後移植到 Material UI v5——敬請期待。

透過 Toolpad Core 的全端應用程式

為了幫助您比以往更快地建構全端應用程式,我們正在推出 Toolpad Core,這是一個使用 Material UI 和 Next.js 建構儀表板和內部工具的框架,它已經為您配置了路由、版面配置元件和身分驗證。

敬請期待有關 Toolpad Core 的更多更新。

開始使用 Material UI v6

準備好升級到 Material UI v6 了嗎?接下來請前往 v6 遷移指南

請造訪以下連結,以取得此處涵蓋的一些主要功能的更多詳細資訊