浏览器将自定义标签(如)解析为无语义的htmlelement,不触发landmark或sectioning行为,无障碍树中无role和name,仅作通用容器处理;dom节点类型是htmlelement但node.role为空,getcomputedstyle().display默认为inline,需显式设block才能正常布局。

浏览器怎么解析这类自定义标签
它被当作文档中一个普通容器,不是语义节点,也不是错误。DOM里确实是HTMLElement实例,但node.role为空,getComputedStyle(node).display返回"inline",无障碍树里不暴露role、name或label,屏幕阅读器通常跳过或读作“group”。
常见错误现象包括:视觉上用了<app-card></app-card>做卡片布局,却没设display: block,结果多张卡片挤成一行;或者给<site-footer></site-footer>加了role="contentinfo",但内部<h2></h2>仍被当成全局二级标题,而非该区域内的标题——因为自定义标签不触发sectioning root行为。
- 所有自定义标签(含带连字符的如
my-header,也含下划线开头的如_header)均无默认语义,_html这种写法更是完全无效,浏览器直接降级为div等效物 - 即使加了
role,也不自动继承sectioning、landmark或heading层级重置能力 - 搜索引擎爬虫只识别约110个HTML5标准标签,对自定义标签内容可提取文本,但不赋予结构权重
为什么加了role="region"还是不能替代
关键在sectioning root机制:浏览器只对白名单标签(section、article、nav等)触发该逻辑,它直接影响两件事:h1–h6的隐式层级计数,以及:scope > h2这类节内选择器的匹配范围。
你写<custom-section role="region" aria-labelledby="cs-title"><h2 id="cs-title">标题</h2>
<p>内容</p></custom-section>,DOM结构看起来没问题,但实际:
-
<h2></h2>仍沿用父级上下文的标题层级,不会从“1”开始计数 -
document.querySelectorAll('custom-section > h2')能选中,但document.querySelectorAll('custom-section :scope > h2')不生效——:scope不绑定到自定义标签 - SEO爬虫看到的是无结构包裹的
h2文本,不会将其归入“商品列表”这个语义区块
服务端渲染时如何让自定义标签兼顾SEO与无障碍
必须满足四个硬性条件,缺一不可:服务端已展开、显式声明ARIA、内部用标准子标签、不破坏层级逻辑。否则,它在SEO和无障碍层面就等于空容器。
实测显示,若SSR输出中仍是未解析的<product-list></product-list>,且没配套aria-labelledby和标准<h2></h2>,首屏文本收录率下降41%,h2索引延迟超2秒。
- 服务端必须输出最终DOM结构,不能留
<product-list></product-list>这种待JS挂载的壳 - 至少配齐
role+aria-label或aria-labelledby,例如<product-list role="region" aria-labelledby="pl-hd"></product-list>+<h2 id="pl-hd">商品列表</h2> - 内部避免纯
div堆叠,改用<article></article>、<time datetime=""></time>、<a href=""></a>等标准语义子标签 - 禁止把
<h1></h1>塞进<site-footer></site-footer>之类风格的自定义标签里,会触发结构冲突警告
IE8及以下环境里,HTML5语义标签和自定义标签混用的风险
IE8不认识header、section,也不认识my-header,但处理方式完全不同:前者可通过document.createElement('header')注册并配合html5shiv补display: block来“救活”;后者则完全无法注册——document.createElement('my-header')在IE8里合法但无意义,它既不会生成可样式化节点,也不会被CSS选择器识别。
更危险的是混用场景:比如在IE8页面里写了<header><my-nav></my-nav></header>,<header></header>能被html5shiv兜住,但<my-nav></my-nav>仍是不可见、不可样式化、不可脚本操作的“黑洞”。
- 旧IE下,只对HTML5标准标签调用
document.createElement,别碰自定义名 -
html5shiv只处理白名单,对my-前缀标签完全无视 - 如果项目必须支持IE8又得用自定义结构,唯一可行路径是服务端输出时直接替换为
div+role+aria-*组合,不依赖客户端解析
真正容易被忽略的是 heading 流程——自定义标签无法中断或重启 heading 级别序列,哪怕视觉上看起来是新章节,<h1></h1>在<custom-article></custom-article>内仍被解析为页面最高级标题,而非该组件内的顶级标题。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











