自定义标签在dom中被解析为无语义的htmlelement,node.role为空字符串,display默认为inline,无障碍树中无role和name,屏幕阅读器跳过或仅读作“group”。

自定义标签在DOM里到底算什么节点
浏览器解析 <my-header></my-header> 这类非标准标签时,不会报错,但也不会赋予任何语义——它就是个裸的 HTMLElement,node.role 是空字符串,getComputedStyle(el).display 默认为 inline,无障碍树里既没 role 也没 name,屏幕阅读器通常跳过或只读作“group”。
这不是 bug,是规范行为。HTML 解析器对未知标签采用 “void element fallback” 策略:剥离所有语义上下文,仅作容器处理。
-
<section></section>能重置<h1></h1>的隐式层级计数,<my-section></my-section>不行,哪怕加了role="region" -
document.querySelector('main')匹配不到<my-main></my-main>,因为 selector 不走 role 匹配逻辑 - 搜索引擎只认白名单语义标签,
<custom-card></custom-card>内容会被抓取,但无结构权重
为什么加了 role="main" 还不算 main 区域
加 role="main" 只是告诉辅助技术“这是主内容”,但它不触发浏览器内建的 sectioning root 行为,也不影响 heading 流程、CSS 作用域或 DOM 查询逻辑。
真正容易被忽略的是 heading 层级序列:哪怕视觉上 <my-article><h1>标题</h1></my-article> 看起来是个新章节,这个 <h1></h1> 在解析时仍被当作整个页面的最高级标题,不是该组件内的顶级标题。
- 同一文档中多个
role="main"违反 WCAG,但浏览器不校验,只靠人工检查 -
role="article"要求内容独立可分发,不是所有卡片都满足,误用会导致语义污染 - 仅设
role不够,必须配套aria-label或aria-labelledby,否则屏幕阅读器读不出名称
IE8–IE11 对 HTML5 语义标签的兼容底线
IE8 及更早版本根本不认识 <header></header>、<nav></nav>、<main></main>,它们被当普通未知元素处理:不进 CSS 选择器匹配、不设默认样式、布局直接塌陷。
document.createElement('header') 只解决 DOM 创建问题,但 IE8 的渲染引擎仍默认给这些标签设 display: inline,所以必须手动补 CSS:
article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section {
display: block;
}
- 脚本必须放在
最顶部,在任何 CSS 加载前执行 - 条件注释推荐写法:
<!--[if lt IE 9]><script src="html5shiv.min.js"></script><![endif]--> -
html5shiv 本身不设
display: block,它只注入基础样式;若 CDN 失效,降级就断链,内联三行脚本更稳
想用自定义标签又保语义?必须显式补全 ARIA 链
Web Components 场景下坚持用 <app-header></app-header>,就不能依赖浏览器自动推导——语义得手把手教给辅助技术。
基础语义链至少包含三环:角色 + 名称 + 上下文。漏掉任意一环,屏幕阅读器就“看不见”。
- 导航区域:用
role="navigation",且内部必须含至少一个可聚焦链接(<a href></a>或带tabindex="0"的元素) - 主内容区:用
role="main"+aria-label="首页主要内容",避免靠aria-labelledby引用不存在的 ID - 不要给
<my-card></my-card>加role="article",除非它真能单独 RSS 订阅或被搜索引擎作为独立页面索引
最常被跳过的环节是 heading 流程控制——自定义标签无法中断或重启标题层级,这点没法靠 ARIA 补救,只能靠结构设计规避。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











