ZiMingの宝藏之地
首页项目归档笔记照片墙音乐灵境说说杂谈友链关于
知识库
138 篇文档 / 65 个目录
目录菜单
主页知识库
飞书飞书知识库/前端/前端浏览器兼容性问题

前端浏览器兼容性问题

同步时间:2026-05-26T15:20:19

https://juejin.cn/post/7368302351213903911

总结: 高阶语法降级处理

    • 利用 PostCSS 和 Babel 搞定常规问题
  • *-- 结合 webpack 提高效率 **项目的自动化编译转换PostCSS,Babel
  • -结合 rollup 提高效率
  • 其他特殊场景*

  • *Web Components 兼容性 **

  • *HTML 标签属性大小写兼容性 **

  • 特定样式显示的兼容性*

PostCSS

PostCSS : 用 JS 插件转换样式的工具,自动添加浏览器私有前缀(如 -webkit-、-moz-、-ms-),转换新的 CSS 特性以适应低版本浏览器,

Babel

Babel : 根据配置文件中的规则将高版本 JavaScript 转换为目标版本的 JavaScript 代码,从而确保在不同环境中的兼容性。

rollup

rollup:是一个备受欢迎的现代化 JavaScript 模块打包工具,它专注于将现代的 JavaScript 代码(尤其是 ES6+ 模块化代码)打包成更小、更高效的输出。相较于 Webpack,尤其在构建库或框架时,它的优势更为明显。

Web Components 兼容性

在使用 Web Components 时,我们需要注意浏览器对自定义元素、Shadow DOM、HTML Templates 和 HTML Imports 的原生支持程度。即使使用了工具如 Babel,仍需考虑浏览器差异和标准化进程,一般可以借助 webcomponents.org 官方提供的 polyfills,如 @webcomponents/webcomponentsjs ,下面将简述配置步骤。

  • 首先,执行如下安装命令:*
bash

 代码解读
复制代码$ npm install @webcomponents/webcomponentsjs
// 应用代码中引入库
import "@webcomponents/webcomponentsjs";
  • 或者通过 script 引用的方式:*
html

 代码解读
复制代码<script src="node_modules/@webcomponents/webcomponentsjs/webcomponents-bundle.js"></script>
  • 其次,在项目中就可以放心使用 Web Component Api 了。*

HTML 标签属性大小写兼容性

在开发中使用 Web Components 构建自定义元素时,尽管我们已经引入了 @webcomponents/webcomponentsjs 这个垫片(polyfill),并解决了一般兼容性问题,但有时仍会面临一些其他问题,例如在特定情况下无法正确监听属性值变更的问题。当前,这个问题在 iOS 10 的手机上真实存在。

遇到这种特殊的兼容性问题,通常需要耐心地进行反复实验,以找到问题的根本原因。

在 Web Components 中,监听属性变更主要通过一个名为 observedAttributes 的静态属性来定义需要观察的属性,然后通过 attributeChangedCallback() 生命周期回调来进行实际的监听。因此,为了解决这类特殊兼容性问题,我们进行了以下测试实验:

【常规使用方式】

html

 代码解读
复制代码/** 自定义组件调用 */
<my-custom-element size="100" bigSize="200"></my-custom-element>
// 自定义组件实现 class MyCustomElement extends HTMLElement { static
observedAttributes = ["size", "bigSize"]; // 属性定义 constructor() { super(); }
attributeChangedCallback(name, oldValue, newValue) { // 相应值监听
console.log(`属性 ${name} 已由 ${oldValue} 变更为 ${newValue}。`); } }
customElements.define("my-custom-element", MyCustomElement);

【测试 1】:监听 size 和 bigSize

javascript

 代码解读
复制代码static observedAttributes = ["size","bigSize"]; // 驼峰

结果:attributeChangedCallback 只能够监听到 size

【测试 2】:监听 size 和 bigsize

javascript

 代码解读
复制代码static observedAttributes = ["size","bigsize"]; // 全小写

结果:attributeChangedCallback 监听到 size 和 bigsize,但是非 iOS 10 的设备监听失效

【测试 3】:监听 size 、 bigsize 和 bigSize

javascript

 代码解读
复制代码static observedAttributes = ["size","bigsize","bigSize"]; // 驼峰 + 全小写

结果:attributeChangedCallback 在 iOS 10 设备监听到 size 和 bigsize。非 iOS 10 设备监听到 size 和 bigSize。

【实验结论】

通过多次实验,我们发现在 iOS 10 的手机上,自定义元素中定义的所有驼峰形式的属性都无法正常生效,而全小写的属性依然能够正常使用。因此,在处理 HTML 标签属性的兼容性时,我们有两种主要选择:

  • 1、在业务使用侧进行语法规避: 确保在自定义组件的属性定义中,将所有属性修改为全小写形式。

  • 2、动态处理 observedAttributes: 判断 observedAttributes 中的属性值,如果存在驼峰形式的属性,动态添加相应的全小写形式属性,并调整监听逻辑。

如果我们使用一些第三方库来创建 Web Components 元素,且遇到类似问题,可以考虑在框架底层也进行相应的调整。例如,对于使用 lit-element 库的情况,可以根据下述代码进行调整:

javascript

 代码解读
复制代码// updating-element.js
static get observedAttributes() {
    this.finalize();
    const attributes = [];
    this._classProperties.forEach((v, p) => {
      const attr = this._attributeNameForProperty(p, v);
      if (attr !== undefined) {
        this._attributeToPropertyMap.set(attr, p);
        attributes.push(attr);

        // 兼容低版本系统属性值处理,动态注入全小写监听属性
        const attrToLower = attr.toLowerCase();
        if (attr !== attrToLower) {
          this._attributeToPropertyMap.set(attrToLower, p);
          attributes.push(attrToLower);
        }
      }
    });
    return attributes;
  }

。

特定样式显示的兼容性

除了一般的 JavaScript 语法和 API ,以及一些浏览器特性能力的兼容问题外,还有一些常见的移动端兼容问题,需要根据具体情况采用不同的解决方案,以确保在不同设备上都能获得一致的显示效果。这里单独对 border 1px 在移动端显示问题 进行简单说明。

【问题一:Retina 屏幕的 1px 像素问题】

这里的 1px 问题指的是在一些 Retina 屏幕的设备上,移动端页面中设置的 1px 边框会显得比实际的 1px 更加粗。这种现象的原因很简单,CSS 中的 1px 并不能与移动设备屏幕上的 1px 完全对应。它们之间的比例关系由一个专门的属性来描述:

javascript

 代码解读
复制代码// 设备像素比
window.devicePixelRatio = 设备的物理像素 / CSS像素;

常见的解决方案其实非常多,建议根据实际情况进行选择。

方案 优点 缺点
直接写 0.5px 代码简单 IOS 及 Android 老设备不支持
用图片代替边框 全机型兼容 修改颜色及不支持圆角
background 渐变 全机型兼容 代码多及不支持圆角
box-shadow 模拟边框实现 全机型兼容 有边框和虚影无法实现
伪元素先放大后缩小 简单实用 缺点不明显
设置 viewport 解决问题 一套代码适用所有页面 缺点不明显

【问题二:border 1px 转为 rem 单位时不显示】

通过在 Chrome 中查看元素,我们可以发现实际上 border 仍然存在,只是 1px 被转换为非常小的 rem 数值(例如:0.01333rem)。这导致在部分安卓设备上可能出现 border 不显示的情况。这类兼容性问题主要是由于各大浏览器厂商在处理较小数值时的策略不同所导致的。一种常见的解决方式是通过使用伪元素的放大和缩小来调整,参考如下:

css

 代码解读
复制代码.scale {
  position: relative;
  border: none;
}
.scale:after {
  content: "";
  position: absolute;
  bottom: 0;
  background: #000;
  width: 100%;
  height: 2px; // 放大两倍
  transform: scaleY(0.5); // 再缩小
  transform-origin: 0 0;
}

Table of Contents