logoAnt Design

⌘ K
  • 设计
  • 研发
  • 组件
  • 博客
  • 资源
  • 国内镜像
5.27.5
  • v6 的一些 CSS 琐事
  • 👀 视觉回归测试
  • 为什么禁用日期这么难?
  • 封装 Form.Item 实现数组转对象
  • 行省略计算
  • 📢 v4 维护周期截止
  • antd 里常用的 TypeScript 工具方法
  • 一个构建的幽灵
  • 当 Ant Design 遇上 CSS 变量
  • API 的历史债务
  • 灵动的 Notification
  • 色彩模型与颜色选择器
  • 主题拓展
  • 虚拟表格来了!
  • 快乐工作主题(一)
  • 动态样式去哪儿了?
  • Suspense 引发的样式丢失问题
  • 打包体积优化
  • 你好,GitHub Actions
  • 所见即所得
  • 静态方法之痛
  • SSR 静态样式导出
  • 依赖排查
  • 贡献者开发维护指南
  • 转载-如何提交无法解答的问题
  • 新的 Tooltip 对齐方式
  • 非必要的渲染
  • 如何成长为 Collaborator
  • Modal hook 的有趣 BUG
  • antd 测试库迁移的那些事儿
  • Tree 的勾选传导
  • getContainer 的一些变化
  • 组件级别的 CSS-in-JS
变体
样式覆盖
条件兼容
条件样式
@scope
影响范围

v6 的一些 CSS 琐事

2025-05-23
@zombieJ
文档贡献者
👀 视觉回归测试

相关资源

Ant Design X
Ant Design Charts
Ant Design Pro
Pro Components
Ant Design Mobile
Ant Design Mini
Ant Design Web3
Ant Design Landing-首页模板集
Scaffolds-脚手架市场
Umi-React 应用开发框架
dumi-组件/文档研发工具
qiankun-微前端框架
Ant Motion-设计动效
国内镜像站点 🇨🇳

社区

Awesome Ant Design
Medium
X
yuque logoAnt Design 语雀专栏
Ant Design 知乎专栏
体验科技专栏
seeconf logoSEE Conf-蚂蚁体验科技大会
加入我们

帮助

GitHub
更新日志
常见问题
报告 Bug
议题
讨论区
StackOverflow
SegmentFault

Ant XTech logo更多产品

yuque logo语雀-构建你的数字花园
AntV logoAntV-数据可视化解决方案
Egg logoEgg-企业级 Node.js 框架
Kitchen logoKitchen-Sketch 工具集
Galacean logoGalacean-互动图形解决方案
WeaveFox logoWeaveFox-前端智能研发
xtech logo蚂蚁体验科技
主题编辑器
Made with ❤ by
蚂蚁集团和 Ant Design 开源社区
loading

Ant Design v6 的开发过程中,由于不需要再考虑 IE 的兼容问题,我们对部分组件改造使用了 CSS 变量获得了更小的 CSS 体积以及更好的性能。今天我们来聊聊 CSS 变量的一些小事。

变体

在 v5 中一些组件支持 variant 属性来实现不同的样式,Button 组件就是一个典型例子:

Variant Button

(配合 color 实现了不同的按钮组合)

在 v5 中,Button 的变体与颜色组合会创建一套重复的排列组合样式:

css
/* Sample code. Not used in real world. */
.ant-btn-solid.ant-btn-red {
color: #fff;
background: red;
}
.ant-btn-solid.ant-btn-blue {
color: #fff;
background: blue;
}
.ant-btn-outlined.ant-btn-red {
color: #fff;
border: 1px solid red;
}
.ant-btn-outlined.ant-btn-blue {
color: #fff;
border: 1px solid blue;
}
/* ... */

转换成 CSS 变量后,逻辑就会从样式转成对色板的控制。因而在定义完一套基础色板后,就可以通过变量简单的量产样式:

css
/* Sample code. Not used in real world. */
/* Template Part */
.ant-btn {
color: var(--ant-btn-color);
background: var(--ant-btn-background);
border-color: var(--ant-btn-border-color);
border-width: 1px;
border-style: solid;
}
.ant-btn-solid {
--ant-btn-color: #fff;
--ant-btn-background: var(--ant-color-solid);
}
.ant-btn-outlined {
--ant-btn-color: var(--ant-color-solid);
--ant-btn-border-color: var(--ant-color-solid);
}
/* CSS Variables. The more color you have, the more size to save. */
.ant-btn-red {
--ant-color-solid: red;
}
.ant-btn-blue {
--ant-color-solid: blue;
}
/* ... */

样式覆盖

在 CSS 变量下,用户侧的样式覆盖也变得更简单了。过去开发者覆盖一个样式需要对各个状态进行覆盖,同时还需要考虑优先级覆盖的情况:

css
.ant-btn-solid.my-btn:not(:disabled) {
background: #f00;
}
.ant-btn-solid.my-btn:not(:disabled):hover {
background: #e00;
}
.ant-btn-solid.my-btn:not(:disabled):active {
background: #d00;
}
.ant-btn-outlined.my-btn:not(:disabled) {
color: #f00;
border-color: #f00;
}
.ant-btn-outlined.my-btn:not(:disabled):hover {
color: #e00;
border-color: #e00;
}
.ant-btn-outlined.my-btn:not(:disabled):active {
color: #d00;
border-color: #d00;
}

而覆盖 CSS 变量则简单很多:

css
.ant-btn-outlined.my-btn {
--ant-color-solid: #f00;
--ant-color-solid-hover: #e00;
--ant-color-solid-active: #d00;
}

条件兼容

v6 为了实现语义化结构,我们对大量组件的 DOM 结构进行了调整,同时也将 v4 至 v5 迁移时的 less 变量兼容提供的对应 Component Token 进行了清理(更多的数值通过计算生成而不是让开发者手工来配置)。但是为了避免对现有用户造成影响,我们是希望尽可能的兼容。

其中一个例子就是某个 token 存在的时候,我们使用另一种样式:

less
.sample {
color: blue;
}
/* How to if? */
if (customVar exist) {
.sample {
color: red;
}
}

一个想法是在组件中根据 token 的存在与否来添加一个额外的 className:

jsx
const Sample = () => {
const { token } = useToken();
// Sad. Component token is not exist in token.
if (token.components.sample.customVar) {
// ...
}
};

但是遗憾的是,组件的 token 在 useToken 中并不存在。它只有在组件的渲染 effect 中才会异步生成从而避免无用的性能浪费。因而在 CSS 中条件判断会是个更好的选择,这里就不卖关子了,使用 @container 便可以实现条件判断:

css
/* Current container support css var `--custom-var` */
@container style(--custom-var) {
/* ... */
}

Without CSS Var

With CSS Var

条件样式

需要注意的是,@container 的 CSS 变量查询目前 Firefox 尚未支持。所以在 v6 中,我们并不会把主要的功能放在 @container 上,而是作为一个兼容兜底逻辑来使用。

@scope

如果说 CSS 中最诱人的属性是什么,那可能非 @scope 莫属了。v5 中,我们使用 :where 来实现 CSS 的命名空间,从而实现多个版本或者主题的 antd 组件的样式隔离:

css
/* Theme 1 */
:where(.css-BamBoo) {
.ant-btn {
color: red;
}
}
/* Theme 2 */
:where(.css-LIghT) {
.ant-btn {
color: blue;
}
}

但是这对于嵌套逻辑来说,偶尔会有一些问题。比如下面的例子中,Theme1 对 span 的样式会影响 Theme2:

css
/* Theme 1 */
:where(.css-BamBoo).component-a span {
color: red;
}
/* Theme 2 */
:where(.css-LIghT).component-b {
color: blue;
}
tsx
<div className="component-a css-BamBoo">
<div className="component-b css-LIghT">
<span>Hello World</span>
</div>
</div>

而 @scope 则可以完美的解决这个问题:

css
@scope (.component-a) to (span) {
/* ... */
}
Should be red
Should be blue
影响范围

但是同样的,@scope 目前也并不被 Firefox 支持。而如果将其应用于 v6 版本,那就会导致 Firefox 用户无法使用 antd 组件。因而我们可能会在下一个大版本中才能见到它的身影。

CodeSandbox Icon
Hitu Icon
codepen icon
External Link Icon
Expand Icon
CodeSandbox Icon
Hitu Icon
codepen icon
External Link Icon
Expand Icon