is属性是定制化内置元素的唯一合法入口,必须配合支持标签(如button、canvas)、customElements.define()中{extends:"xxx"}选项及严格匹配的is值,否则无效且静默忽略。

is 属性在不支持 Customized Built-in Elements 的浏览器中完全被忽略,不会报错,也不会触发任何降级逻辑——它就只是个普通字符串属性。
不支持的浏览器里 is 会变成什么
Chrome 66–、Firefox 62–、Safari 10.0–、Edge ≤18、所有 IE 版本,这些环境压根不识别 is 的语义作用。你写 <button is="my-btn">,浏览器解析后得到的仍是 HTMLButtonElement 实例,this instanceof MyBtn 为 false,customElements.define() 调用直接抛 ReferenceError: customElements is not defined。
关键点是:没有 fallback 行为,也没有“悄悄退化成 autonomous 元素”的机制。它就是无效的 HTML 属性,和写 <button data-is="my-btn"> 效果一样——DOM 中存在,但无任何运行时影响。
为什么不能靠 is 做渐进增强
-
is不是可选特性,而是强依赖底层 Custom Elements v1 + Built-in Extension 两层规范支持;缺一不可 - 即使你用
try/catch包住customElements.define(),注册失败后,含is的标签仍按原生元素渲染,不会自动切换为<my-btn>或其他替代结构 - 服务端无法根据 UA 注入降级 HTML,因为浏览器根本不解析
is,也就不会触发自定义类的构造函数,无法通过connectedCallback动态补 DOM
真要兼容,只能放弃 is 写法
想覆盖旧浏览器,必须走两条路之一:
立即学习“前端免费学习笔记(深入)”;
- 彻底不用
is,改用 autonomous 自定义元素(如<my-button>),再配合特性检测 + class-based 降级:如果'customElements' in window为false,就用document.createElement('div')模拟,并手动绑定事件、样式、表单逻辑 - 不注册自定义元素,只用原生标签 +
data-属性驱动 JS 行为(如<button data-role="my-button">),把所有逻辑收口到一个初始化函数里,统一处理
注意:<button is="my-btn"> 在旧浏览器里不会变成 HTMLUnknownElement,它始终是 HTMLButtonElement;而 <my-btn> 在 IE 里才是 HTMLUnknownElement,连 querySelector 都找不到。
最容易被忽略的细节
很多人以为加个 if ('customElements' in window) 就能安全用 is,但忘了:就算注册成功,旧版 Safari(≤16.3)对 formAssociated 元素的支持也不完整,form.elements 里漏掉你的 <input is="my-input"> 是静默发生的,验证逻辑直接跳过——这种问题只在真实表单提交时暴露,且无法靠特性检测提前发现。



















