跳到主要内容

跨浏览器兼容处理

场景

项目需要兼容 Chrome、Firefox、Safari、Edge 等主流浏览器,部分用户甚至还在用旧版浏览器。如何系统性地处理兼容问题?

方案设计

1. 特性检测优于浏览器检测

feature-detection.ts
// ❌ 浏览器检测(不可靠)
if (navigator.userAgent.includes('Chrome')) { ... }

// ✅ 特性检测
if ('IntersectionObserver' in window) {
// 使用 IntersectionObserver
} else {
// 降级方案:scroll 事件 + getBoundingClientRect
}

// ✅ CSS 特性检测
if (CSS.supports('display', 'grid')) {
// 使用 Grid 布局
}
CSS @supports
/* CSS 层面特性检测 */
@supports (backdrop-filter: blur(10px)) {
.header { backdrop-filter: blur(10px); }
}
@supports not (backdrop-filter: blur(10px)) {
.header { background: rgba(255, 255, 255, 0.9); }
}

2. Browserslist + 工具链

package.json 或 .browserslistrc
{
"browserslist": [
"> 1%",
"last 2 versions",
"not dead",
"not ie 11"
]
}

这个配置会自动影响:

  • Babel:决定需要转译哪些语法
  • PostCSS/Autoprefixer:决定需要加哪些 CSS 前缀
  • core-js:决定需要哪些 Polyfill

3. Polyfill 策略

按需 Polyfill(推荐)
// Babel + core-js 按需引入
// babel.config.js
export default {
presets: [
['@babel/preset-env', {
useBuiltIns: 'usage', // 按使用自动引入
corejs: 3,
}],
],
};

// 或使用 polyfill.io 动态加载(按浏览器 UA 返回)
// <script src="https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserver,Promise"></script>

4. CSS 兼容速查

CSS 特性兼容方案
Flexbox基本全兼容,注意 Safari 的 gap 支持(15.4+)
GridIE 不支持,其他主流兼容
dvh/svh/lvhSafari 15.4+,降级用 JS 计算
Container QueriesChrome 105+,降级用媒体查询
:has()Safari 15.4+,Chrome 105+,Firefox 121+
color-mix()Chrome 111+,Safari 16.2+

常见面试问题

Q1: 如何制定项目的浏览器兼容策略?

答案

  1. 数据驱动:根据埋点数据分析用户实际浏览器分布,确定支持范围
  2. 配置 Browserslist:统一影响 Babel/PostCSS/ESLint
  3. 分级支持
    • A 级(完全支持):最新 2 版本的 Chrome/Firefox/Safari/Edge
    • B 级(基本可用):功能正常但体验降级
    • C 级(不支持):展示升级提示

Q2: Babel 和 PostCSS 在兼容性中各负责什么?

答案

工具负责范围例子
BabelJS 语法转译 + API Polyfill?. → 普通判断 / Promise.allSettled polyfill
PostCSSCSS 语法转换 + 前缀display: flex-webkit-flex
TypeScript类型擦除 + 语法降级enum → 对象

它们都读取 Browserslist 配置来决定转换范围。

相关链接