因为解决 antd5 在低版本浏览器的文章始终没有解决我的问题,或者是不够优雅,因此做了一点整理,希望对你有用,至少对我是有用的 😁😁😁
调查原因
结果是 css 中是 where 在低版本 chrome 浏览器不起作用
然后就去 caniuse.com/?search=%3A… , 样式不对的浏览器 console 控制台输入 navigator.userAgent 检测浏览器信息,最终结果是 where 不兼容 chrome 88 以下的版本
解决方法
与 antd 有关直接看官方文档,直接去 antd 搜索 :where ,点击 样式兼容 - Ant Design 根据文档进行如下操作:
参考: Ant Design 的 CSS-in-JS 默认通过
:where
选择器降低 CSS Selector 优先级,以减少用户升级时额外调整自定义样式的成本,不过:where
语法的兼容性在低版本浏览器比较差。在某些场景下你如果需要支持旧版浏览器,你可以使用@ant-design/cssinjs
取消默认的降权操作(请注意版本保持与 antd 一致):
解决非静态方法导致的样式错乱
Umi 中 在 app.tsx 中写入 or 如果是自己创建的就在 root 文件中改造如下代码即可
1import { StyleProvider, legacyLogicalPropertiesTransformer } from '@ant-design/cssinjs'
2import { ConfigProvider } from 'antd'
3
4
5export function rootContainer(container: React.ReactNode) {
6 return (
7 <ConfigProvider prefixCls="your-antd-prefix-class-name">
8 // 这个是核心的解决方案,建议不要在项目中多次使用 StyleProvider
9 <StyleProvider hashPriority="high" transformers={[legacyLogicalPropertiesTransformer]}>
10 {container}
11 </StyleProvider>
12 </ConfigProvider>
13 )
14}
解决 message 等通知静态方法的样式丢失问题
antd 中可以直接
message.xxx
、Modal.xxx
、notification.xxx
静态方法调用展示 UI,但是这些静态方法的样式在低版本浏览器中仍然不支持 :where 愈发, 所以需要优雅降级来解决低版本浏览器 where, gap(flex) 等 css 失效问题, 主要参考 App 包裹组件
- 新建 src/compatible/antd.tsx 文件, 这里的 message 等方法可以直接导出使用(核心就是使用闭包解决)
1
2
3说明: 兼容低版本的浏览器,antd 的部分组件需要做兼容处理
4参考 https://ant-design.antgroup.com/components/app-cn#app-demo-config
5*/
6
7import { App } from 'antd'
8import { useEffect } from 'react'
9import type { MessageInstance } from 'antd/es/message/interface'
10import type { ModalStaticFunctions } from 'antd/es/modal/confirm'
11import type { NotificationInstance } from 'antd/es/notification/interface'
12import { useEventListener } from 'ahooks'
13import { detect } from 'detect-browser'
14
15const browser = detect()
16
17let message: MessageInstance
18let notification: NotificationInstance
19let modal: Omit<ModalStaticFunctions, 'warn'>
20
21const antd5Prefix = 'your-antd-prefix-class-name'
22
23
24const compatibleCss = `
25 .${antd5Prefix}-btn .${antd5Prefix}-btn-icon {
26 display: inline-block !important;
27 margin-right: 0.25rem !important;
28 }
29`
30
31type CompatibleContainerProps = {
32 children: React.ReactNode
33}
34
35export const CompatibleContainer:React.FC<CompatibleContainerProps> = ({children}) => {
36 useEffect(() => {
37
38 if (browser?.name === 'chrome' && parseFloat(browser.version) <= 80) {
39 const compatibleStyleTag = document.createElement('style')
40
41 compatibleStyleTag.innerHTML = compatibleCss
42 document.head.appendChild(compatibleStyleTag)
43 }
44 }, [])
45
46
47 const staticFunction = App.useApp()
48
49 message = staticFunction.message
50 modal = staticFunction.modal
51 notification = staticFunction.notification
52
53 return children
54}
55
56export { message, notification, modal }
- 更新 src/app.tsx(umi版本)其他雷同
1import { CompatibleContainer, notification } from './compatible'
2import { ClickToComponent } from 'click-to-react-component'
3
4export function rootContainer(container: React.ReactNode) {
5 return (
6 <ConfigProvider theme={theme} prefixCls="ant5">
7 <StyleProvider hashPriority="high" transformers={[legacyLogicalPropertiesTransformer]}>
8 <App style={{ height: '100%' }}>
9 <CompatibleContainer>{container}<CompatibleContainer/>
10 <ClickToComponent />
11 </App>
12 </StyleProvider>
13 </ConfigProvider>
14 )
15}
16
17export const request: RequestConfig = {
18 errorConfig: {
19 errorHandler: (e: Record<string, any>) => {
20 // 这里的 notification 就不会有样式丢失的问题
21 notification?.error({
22 message: "请求错误",
23 description: e.message || "未知错误,请联系xxx解决",
24 })
25 }
26 ...
27 }
28 }
个人笔记记录 2021 ~ 2025