未知标签被浏览器静默降级为无语义容器,DOM中类型因内核而异(Chrome/Firefox/Edge104+为HTMLElement,IE/Safari15.3-为HTMLUnknownElement),nodeType恒为1,display默认inline,不触发默认样式、sectioning root或heading重置,querySelector无法通过语义名匹配,无障碍树中被忽略或仅读作“group”,拼错标签如<divv>可降级为HTMLUnknownElement,而<_html>等非法标签名会导致DOM断裂。

浏览器对未知标签不做报错处理,而是静默降级为无语义容器——它既不是真正的语义元素,也不等同于 div,但行为上最接近未设 role 的 div。
未知标签在 DOM 中到底是什么类型
取决于浏览器内核和版本:document.createElement('my-header').constructor.name 在 Chrome/Firefox/Edge 104+ 中返回 HTMLElement,但在 IE8–IE11 或 Safari 15.3 及更早中返回 HTMLUnknownElement。这不是 bug,是 HTML 解析器的 fallback 行为:不识别就剥离语义,只留壳。
-
node.nodeType恒为1(Node.ELEMENT_NODE),但node.role始终为空字符串 -
getComputedStyle(el).display默认是"inline",不是"block",所以宽高、margin、padding 全部失效,除非显式设置display: block或flex - 它不会进入浏览器的“标准元素分类表”,因此不触发任何默认样式、sectioning root 行为或 heading 层级重置
为什么 querySelector('header') 匹配不到 <my-header>
CSS 选择器和 DOM 查询逻辑完全不走 role 或语义推断,只认白名单标签名。即使你给 <my-header role="banner"> 加了 ARIA 角色,document.querySelector('header') 依然返回 null。
- 必须用
querySelector('my-header')或属性选择器(如querySelector('[role="banner"]'))才能命中 -
document.querySelectorAll(':scope > h2')在<my-section>内执行时,:scope不继承 sectioning root,实际匹配的是整个文档的h2,不是该标签内部的子节点 - 搜索引擎、无障碍树、屏幕阅读器全部跳过该节点,或仅读作 “group”,因为它在无障碍树中既无
role也无name
<_html> 和拼错标签(如 <divv>)处理方式不同
<_html> 违反 HTML5 标签名规范(必须字母开头、不含下划线),浏览器直接当非法字符串处理;而 <divv> 是“可识别但不存在”的标签,会被降级为 HTMLUnknownElement,但至少保留标签名。
立即学习“前端免费学习笔记(深入)”;
-
<_html><_head><title>测试</title></_head><_body><p>Hello</p></_body></_html>解析后生成多个孤立的HTMLElement,无父子关系,DOM 结构完全断裂 - 旧版 WebKit(如 Safari 15.3)可能将其降级为纯文本节点;Chrome 虽保留标签名,但不赋予任何语义或布局能力
- W3C 验证器会明确报错:
Element _html is not supported,且 SSR/SSG 输出中会导致爬虫对 DOM 深度判断失准,实测首屏文本收录率下降超 40%
真正容易被忽略的是 heading 层级序列——无论你套多少层 <my-article><h1>标题</h1></my-article>,这个 h1 在解析时仍被当作整个页面的最高级标题,不是组件内的新章节起点。sectioning root 行为无法靠 ARIA 模拟,只能用白名单标签硬实现。



















