开始 · Tailwind
搭配使用
更优雅地使用 TailwindCSS 与 Semi

注意


本页将提供 TailwindCSS 等原子类样式库与 Semi 共同使用时遇到的一些问题的最佳实践。
这些问题在其他组件库与 Tailwind 共同使用时候也会经常遇到,但 Semi 提供了官方解决方案,建议按照本文说明,正确配置项目。
注意
Semi 不依赖任何第三方样式库,没有安装 Tailwind 一样可以运行,如果你没有使用 Tailwind 等原子类库,请直接关闭此页即可。

1. 解决样式覆盖优先级问题

问题表现

在组件中使用部分原子类时没有效果 或 组件库样式异常。

原因分析

使用 Tailwind 时,Tailwind 通过 className 对 dom 进行样式修改,同样作用于 Semi 组件库。同时 Tailwind 默认开启了 Preflight 来重置浏览器默认样式。
此时根据你项目的配置和入口的 import,有两种可能:
  1. Tailwind 比 Semi 的样式先引入,Semi 优先级更高
  2. Semi 样式 比 Tailwind 先引入,Tailwind 优先级更高
如果是 1,则会出现 Tailwind 在添加某些原子类时,如果组件样式已经定义了某个 css 属性,原子类的优先级比 Semi 优先级低,此时原子类失效。 例如在 1 的前提下,对 Button 组件设置 padding,会出现失效的情况。
如果是2,因为 Tailwind 优先级较高,其对浏览器默认样式覆盖的 Preflight 会同时覆盖掉 Semi 的样式。 例如在 2 的前提下,light 的 Button 的背景色会被覆盖为 transparent,导致样式表现异常。

解决方案

无论 Tailwind 和 组件库哪一方优先级高,都会出现问题,因此解决方式在于正确处理 Tailwind 样式中 Preflight 和用户需要的原子类的优先级相对于组件库优先级的关系。
1. 开启 Semi 插件 (>= 2.59.0)
2. 在项目中的配置文件中
  • webpack 用户: 在webpack.config.js 引入Semi webpack 插件并开启 cssLayer
  • rspack 用户: 在 rspack.config.js 引入Semi webpack 插件并开启 cssLayer
使用非 webpack rspack 构建的用户请参照原理自行对 semi 的 css 进行 layer 包裹
3. 修改 Tailwind 入口配置
Tailwind 入口的 CSS 通常是包含了下面三行的文件
将其修改为(直接复制)
并在项目的 JS 入口文件(即 App.tsx 或 index.js)处最上方 import 上面修改的文件。(通常一个 Tailwind 项目对于上面文件的 import 已经处理好,只要将该 import 语句提到所有 import 语句前即可)
兼容低版本浏览器
CSS Layer 要求浏览器版本高于 Chromium 99 (兼容性表格),如果你的网站需要低版本浏览器访问,需要添加 CSS Layer 的 Polyfill,请参考此 Polyfill 的 PostCSS 插件文档

原理

通过 CSS Layer 特性,实现不同来源的样式的优先级设置。
开启插件后,所有的 Semi 样式都会被 @layer {xxxx} 包裹。另外,我们也手动设置了项目中的 Tailwind 的各种类型的样式的 Layer。
另外,我们配置了各种 Layer 的优先级顺序:
上述 CSS 的含义为, base (含 Preflight)优先级最低,Semi 次之,用户设置的原子类样式(padding-[xxx] 等)优先级最高,这样即可解决上面遇到的问题。

2.解决在 Tailwind 原子类中使用 Semi Token 的问题 (可选)

Tailwind 支持用户配置自己的 Token 来实现主题。同时 Semi 也提供了自己的主题方案与对应 Token 如果想在项目中直接使用 Semi Token,例如将一个 span 的文字颜色设置为 --semi-color-text-0 来实现亮暗色的颜色自动切换与主题保持一致,需要单独设置 css color: var(--semi-color-text-0),很不方便。
Semi 提供了 Tailwind 的主题配置文件,用于将 Semi 的 Token 映射为原子类 Token,上述需求可以直接给 span 设置 text-semi-color-text-0 即可。
在 Tailwind 配置中(即 tainwind.config.js)配置以下内容即可: