Material UI 颜色体系实战:从 Material Design 调色板到 createTheme 的调色方案
本文以 Material UI(MUI)官方文档 Color 页面 为主体,系统讲解如何用 Material Design 颜色体系为你的 React 应用设计品牌色主题。读完后你将掌握:@mui/material/colors 调色板的结构(Hue/Shade)与引用方式、createTheme() 中 palette 配置的完整写法、createTheme() 如何自动推导 light/dark/contrastText 的底层机制(对应源码 createPalette.js),以及如何对照 WCAG 2.2 调整对比度阈值。
1. Material Design 颜色系统概述
Material UI 开箱即用地实现了 Google Material Design 指南中的全部颜色。你可以基于 Material Design 颜色体系构建一个反映品牌或产品风格的色彩主题。核心概念只有两个:
- Palette(调色板):一组由色相(hue)及其深浅(shade)组成的颜色集合。Material UI 提供了 Material Design 指南中的全部颜色,且这些颜色在设计上彼此协调。
- Hue & Shade(色相与深浅):调色板中的单个颜色由一个色相(如 "red")和一个深浅(如 "500")共同标识。"red 50" 是最浅的红(偏粉色),"red 900" 是最深的红。此外,大多数色相还带有一组以
A为前缀的 "accent" 深浅(A100/A200/A400/A700)。
2. 引用 2014 版 Material Design 调色板
这套调色板最初由 Material Design 于 2014 年创建,由一组设计上和谐共处的颜色组成,可直接用于开发品牌调色板。若要生成自己的一套和谐调色板,可使用第 3 节的调色板生成工具。
给定一个色相(HUE,如 red、pink)和一个深浅(SHADE,如 500、600),可以这样导入颜色:
import { red } from '@mui/material/colors';
const color = red[500];
仓库中该调色板的实现位于 packages/mui-material/src/colors/ 目录。以 red.js 为例,每个颜色文件导出一个以深浅为键、以 HEX 值为值的对象:
const red = {
50: '#ffebee',
100: '#ffcdd2',
200: '#ef9a9a',
300: '#e57373',
400: '#ef5350',
500: '#f44336',
600: '#e53935',
700: '#d32f2f',
800: '#c62828',
900: '#b71c1c',
A100: '#ff8a80',
A200: '#ff5252',
A400: '#ff1744',
A700: '#d50000',
};
调色板全貌
从 index.js 的导出可以看到,MUI 共内置 20 个色相调色板:
| 色相(camelCase 导出名) | 说明 | 色相(camelCase 导出名) | 说明 |
|---|---|---|---|
red / pink |
红 / 粉 | green / lightGreen |
绿 / 浅绿 |
purple / deepPurple |
紫 / 深紫 | lime / yellow |
青柠 / 黄 |
indigo / blue |
靛蓝 / 蓝 | amber / orange |
琥珀 / 橙 |
lightBlue / cyan |
浅蓝 / 青 | deepOrange / brown |
深橙 / 棕 |
teal |
蓝绿 | grey / blueGrey |
灰 / 蓝灰 |
另外还有一个 common.js,仅含两个基础色:black: '#000' 与 white: '#fff'。
每个色相的深浅结构在官方示例 Color.js 中体现得很清楚:主深浅序列为 50, 100, 200, 300, 400, 500, 600, 700, 800, 900,accent 序列为 A100, A200, A400, A700。
引用示例
例如,引用互补的主色 "red 500" 和强调色 "purple A200":
import { purple, red } from '@mui/material/colors';
const primary = red[500]; // #f44336
const accent = purple['A200']; // #e040fb
const accent = purple.A200; // #e040fb(等价写法)
3. 挑选颜色(Picking colors)
3.1 官方调色工具
Material Design 团队提供了一个官方的调色板配置工具:material.io/resources/color/。它可以帮助你为 UI 创建调色板,并测量任意颜色组合的无障碍等级。工具的输出可以直接填入 createTheme() 函数:
import { createTheme } from '@mui/material/styles';
const theme = createTheme({
palette: {
primary: {
light: '#757ce8',
main: '#3f50b5',
dark: '#002884',
contrastText: '#fff',
},
secondary: {
light: '#ff7961',
main: '#f44336',
dark: '#ba000d',
contrastText: '#000',
},
},
});
3.2 文档内 Playground
Material UI 文档内置了一个交互 Playground(实现见 ColorTool.js),可以在文档站点上直接测试颜色方案:
- 通过色相单选按钮(hues:red、pink、purple、deepPurple、indigo、blue、lightBlue、cyan、teal、green、lightGreen、lime、yellow、amber、orange、deepOrange)与深浅滑块(50~900 及 A100~A700)选择颜色;
- 也可以直接在 Primary / Secondary 输入框中输入 HEX 或
rgb()值,输入框会做正则校验(isRgb/isHex),仅合法颜色才会应用到主题。
Playground 生成的 palette 输出可以直接粘贴到 createTheme() 函数(配合 ThemeProvider 使用):
import { createTheme } from '@mui/material/styles';
import { purple } from '@mui/material/colors';
const theme = createTheme({
palette: {
primary: {
main: purple[500],
},
secondary: {
main: '#f44336',
},
},
});
只需要提供 main 深浅(除非你想进一步定制 light、dark 或 contrastText),其余颜色由 createTheme() 自动计算。如果你直接传入 Material 调色板对象(如 primary: purple),createTheme() 会从该调色板中选取对应的默认深浅填充 main、light、dark——这一点由源码中的 augmentColor 逻辑保证,见下文第 5 节。
3.3 社区工具
官方文档还推荐了这些社区调色工具,用于快速生成、预览和编辑 MUI 主题:
- mui-theme-creator:帮助设计与定制 Material UI 主题的工具,内置多种站点模板,展示各组件受主题影响的效果;
- MUI Theme Builder:生成、预览、编辑 Material UI 主题的工具;
- Material palette generator:即官方调色板生成器,可为任意输入颜色生成一套调色板;
- MUI Theme Customizer:让实验和生成 Material UI 主题更加便捷的工具。
4. 底层原理:createTheme 如何"增强"你的颜色
文档说"只需提供 main",其依据在 createPalette.js 的 augmentColor 函数中。它的工作流程如下:
- 补全
main:若你只传了primary: red(即传入了完整调色板对象),augmentColor({ color, mainShade = 500, ... })会取color[500]作为main;secondary 则默认取A400(light 取A200、dark 取A700); - 校验:颜色对象必须含有
main或500属性,且color.main必须是字符串,否则会抛出带修复建议的错误(错误信息中直接给出了primary: green与primary: { main: green[500] }两种正确写法); - 推导
light/dark:由addLightOrDark调用 colorManipulator 的lighten/darken,按tonalOffset(默认0.2,dark 方向乘以 1.5)把main的亮度上移/下移约两档; - 推导
contrastText:由getContrastText(color.main)完成,即在黑(rgba(0,0,0,0.87))与白(#fff)之间选择对比度更高的一方,达到contrastThreshold(默认 3)。
默认调色板的取值也在同一文件中定义:light 模式下 primary 为 blue 700/400/800,secondary 为 purple 500/300/700,error 为 red 700/400/800,warning、info、success 分别基于 orange、lightBlue、green 调色板;dark 模式则整体改用更亮的深浅(如 primary 取 blue 200/50/400)。若你什么都不配置,主题就是这套默认值。
Playground 中"色条预览"展示的三个方块(dark/main/light)正是调用 theme.palette.augmentColor({ color: { main } }) 得到的结果(见 ColorTool.js 中 colorBar 函数),这与 createTheme() 内部走的完全是同一条代码路径。
5. 无障碍对比度(Accessibility)
WCAG 2.2 Success Criterion 1.4.3 建议文本与图片文本的视觉呈现至少保持 4.5:1 的对比度。Material UI 当前仅强制 3:1 的对比度。从源码看,这一阈值就是 createPalette 中的 contrastThreshold = 3 默认参数:getContrastText 用它判断黑白二选一,且在非 production 环境下,若最终对比度仍低于 3:1,会向控制台打印警告(指明 WCAG 2008 版对比度条款)。
若希望达到 WCAG 2.2 Level AA 合规,可以在 createTheme 的 palette 中调高最小对比度阈值,具体方法见官方 Theme customization(palette) 页面的 Accessibility 小节:
import { createTheme } from '@mui/material/styles';
const theme = createTheme({
palette: {
contrastThreshold: 4.5, // 提高至 WCAG 2.2 AA 建议值
},
});
6. 小结
- 用
import { red } from '@mui/material/colors'+red[500]的"Hue + Shade"方式从 2014 版 Material 调色板中取色,共 20 个色相、每色相 10 档主深浅 + 4 档 A 深浅; - 主题配置只需给
palette.primary/secondary的main,createTheme()会经augmentColor自动推导light、dark、contrastText(推导逻辑见 createPalette.js); - 选色可用 Material Design 官方调色工具、MUI 文档内 Playground 及多个社区主题工具;
- 需要 WCAG 2.2 AA 对比度时,调高
palette.contrastThreshold(MUI 默认为 3:1)。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00