is属性在现代浏览器中基本不可用,chrome 95+已移除支持,firefox和safari从未实现;w3c将其标记为deprecated,因其破坏可访问性与表单语义;唯一可行方案是使用customelements.define注册独立标签名的自定义元素。

is 属性在现代浏览器中基本不可用
HTML 的 is 属性(即自定义元素的扩展机制)在规范中确实存在,但实际支持非常有限:Chrome 从 95 版本起移除了对 is 的支持,Firefox 和 Safari 从未实现。你现在写 <button is="my-button"></button>,浏览器会直接忽略 is,只当普通 <button></button> 渲染,自定义逻辑完全不会触发。
为什么 is 属性失效不是 bug 而是标准退场
Web Components 规范早期允许用 is 扩展原生标签,但实践发现它带来严重兼容性与语义风险:比如 <input is="date-picker"> 看似复用原生 input,实则破坏了表单可访问性、焦点管理、内置验证等行为,且无法保证所有 UA 正确降级。W3C 最终将该特性标记为“deprecated”,主流引擎陆续移除。
- Chrome 95+:解析时静默丢弃
is属性,不报错也不生效 - Firefox/Safari:始终不识别
is,当作未知属性处理 - 服务端渲染或 SSR 框架(如 Next.js)中若生成
is,客户端仍无效
真正可行的替代方案只有 customElements.define
必须用独立标签名注册自定义元素,例如 customElements.define("my-button", MyButton),然后直接使用 <my-button></my-button>。想保留原生语义?只能手动在自定义元素内部封装原生标签,并显式透传属性/事件:
class MyButton extends HTMLElement {
connectedCallback() {
this.innerHTML = `<button type="${this.getAttribute('type') || 'button'}">
${this.innerHTML}
</button>`;
this.querySelector('button').onclick = () => this.dispatchEvent(new Event('click'));
}
}
注意:这里没有 magic —— type、disabled、form 等需手动同步,否则原生行为(如表单提交)就丢失了。
框架里别碰 is,优先用 wrapper 组件
React/Vue/Svelte 中所谓“用 is 继承 button”本质是幻觉。真实做法是写一个 MyButton 组件,内部用 <button></button> 并接收所有原生 props:
- React:用
...props展开到<button></button>,但要过滤掉非原生 prop(如onCustomClick) - Vue:用
v-bind="$attrs"透传,配合inheritAttrs: false - 注意
ref不能直接绑定到原生<button></button>上,需用defineExpose或forwardRef
最常被忽略的一点:键盘交互(Enter/Space 触发点击)、无障碍角色(role)、focus 状态样式——这些都得自己补,浏览器不会因为写了 is 就自动给你。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











