antd v5 在 Chrome 87 上样式失效?问题根源是`:where` 伪类

312 阅读3分钟

最近一个项目,上线之后样式完全乱了,找了半天最终确定到,是antd引入的css where在chrome87上不支持。

问题根源::where 的浏览器兼容性

根据 Ant Design 官方,antd v5 为了解决 CSS-in-JS 方案中样式权重过高的问题,默认采用了 :where 伪类来包裹其组件的样式选择器。这样做的好处是可以有效降低选择器的优先级,使得用户自定义样式能够更轻松地覆盖原有样式。

然而,:where 伪类并非一开始就获得了所有浏览器的支持。根据 MDN 和 antd 官方的兼容性列表,Chrome 浏览器从 88 版本才开始正式支持 :where 伪类。因此,当用户使用 Chrome 87 或更早版本访问页面时,浏览器无法解析 antd 生成的 CSS 规则,导致组件样式无法正确加载。

官方解决方案:StyleProvider 降级处理

针对这一兼容性问题,Ant Design 官方提供了明确且便捷的解决方案。只需在应用根组件外层包裹一个来自 @ant-design/cssinjsStyleProvider 组件,并传入特定属性即可。

具体操作如下:

  1. 安装依赖(如果尚未安装):
    确保项目中已安装 antd 和 @ant-design/cssinjs。通常情况下,@ant-design/cssinjs 会作为 antd 的依赖被自动安装。

  2. 在应用入口处进行配置:
    在应用根组件(通常是 App.jsmain.js/index.js 中的顶层组件)中,引入 StyleProvider 并包裹应用。

    import React from 'react';
    import { StyleProvider } from '@ant-design/cssinjs';
    import MyApp from './MyApp'; // 应用主组件
    
    const App = () => (
      <StyleProvider hashPriority="high">
        <MyApp />
      </StyleProvider>
    );
    
    export default App;
    

工作原理:

通过设置 hashPriority="high",告诉 @ant-design/cssinjs 不要使用 :where(hash) 这种方式来降低优先级,而是生成传统的、不带 :where 伪类的高权重选择器(例如 .css-hash.ant-btn)。这样一来,生成的 CSS 代码就能被 Chrome 87 及其他不支持 :where 的旧版浏览器正确解析,从而恢复组件的正常样式。

其他需要注意的兼容性问题

除了 :where,antd v5 还使用了一些其他的现代 CSS 特性,例如 CSS 逻辑属性margin-inline-start 等),其最低 Chrome 支持版本为 89。如果需要兼容更低版本的浏览器,可能还需要引入相应的转换器。

import { StyleProvider, legacyLogicalPropertiesTransformer } from '@ant-design/cssinjs';

const App = () => (
  <StyleProvider hashPriority="high" transformers={[legacyLogicalPropertiesTransformer]}>
    <MyApp />
  </StyleProvider>
);

总结

  • 首选方案: 强烈建议采用官方推荐的 StyleProvider 方案来解决兼容性问题,这是最直接、最可靠的方法。
  • 告知用户: 如果产品用户群体中仍有相当一部分使用老旧浏览器,可以在页面顶部添加提示,建议用户升级浏览器以获得最佳体验。
  • 了解 antd 浏览器支持策略: Ant Design 官方明确表示,其主要支持现代浏览器的最近两个版本。对于更早的浏览器,则需要开发者自行进行降级处理。