跳到内容
返回博客

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 变量已成为 Web 行业的标准。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

启用该标志后,您可以从 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。我们建议使用基于 ESM 的 CDN,例如 esm.sh,而不是 UMD。有关替代安装方法,请参阅 CDN 文档

通过 Pigment CSS 进行实验性 CSS 提取

Material UI v5 使用 Emotion 作为其默认样式解决方案。由于它是一个运行时 CSS-in-JS 库,Emotion 迫使我们在性能和包大小之间做出妥协。

Material UI v6 引入了与 Pigment CSS 的可选集成,Pigment CSS 是我们新的零运行时样式库,它消除了运行时开销,同时保留了您已经熟悉和喜爱的 API 设计模式。

React Server Components

一旦与 Pigment CSS 集成,Material UI v6 将提供一组单独的布局组件——Grid、Container 和 Stack——它们与 React Server Components 兼容。

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 等包装器来 clutter 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 迁移指南

访问以下链接以获取此处涵盖的一些关键功能的更多详细信息