Community生产力与协作github.com

语义化HTML

审查、重写和解释HTML5语义(标签、地标、标题、表单、ARIA)。当用户粘贴HTML或请求标记审查、正确的标签、可访问性或修复“divitis”时使用。

语义化HTML 是什么?

该技能主要用于审查HTML代码,返回修正后的版本,并解释每个选择背后的理由。它始终聚焦于**纯HTML5**,且与框架无关:即使代码以JSX或其他模板形式出现,也只分析最终生成的标记,并以HTML形式回答。技能的核心价值在于帮助开发者理解语义化对可访问性树(Accessibility Tree)的影响,例如屏幕阅读器如何解读标签,以及如何通过正确的语义标签(如`<button>`、`<nav>`、`<main>`)改善用户体验。它支持任何使用HTML的场景,并提供了一个详细的审查清单,涵盖文档结构、地标、标题层级、交互元素、表单、列表/表格、媒体和ARIA使用规则。响应格式包含诊断(按影响程度分组的问题)、修正后的代码以及针对关键决策的简短解释(关联浏览器/可访问性树行为)。该技能强调优先使用原生HTML元素而非ARIA,并避免过度修正(如将仅用于样式的`<div>`随意替换为`<section>`)。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/lucasaugustsof/skills/tree/HEAD/semantic-html

Installed? Explore more 生产力与协作 skills: steipete/gemini, steipete/gh-issues, steipete/skill-creator · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

语义化 HTML

帮助审查 HTML,返回修正后的版本,并解释每个选择背后的理由。重点始终是纯 HTML5,且与框架无关:如果代码来自 JSX 或其他模板,只分析最终生成的标记,并以 HTML 形式回答。

使用用户使用的语言回复。

为什么语义化很重要(用于解释此点)

浏览器将 HTML 转换为 DOM,并从中构建可访问性树。每个标签都有一个隐式角色(<button> → button,<nav> → navigation,<h2> → heading level 2)。屏幕阅读器、搜索引擎、阅读模式以及扩展程序读取的是该树,而非 CSS。一个样式化为按钮的 <div> 看起来像按钮,但对可访问性树而言,它只是一个通用块:它不接收焦点,不对 Enter/Space 键做出响应,也不会被宣布为按钮。

将解释锚定在此点上——即浏览器理解了什么,以及对于使用页面的人来说发生了什么变化——而不是死记硬背规则。优先使用具体示例(“屏幕阅读器会宣布……”、“Tab 键会跳过此元素……”)而非抽象概念。

有用的思维测试:如果所有 CSS 都消失了,页面的结构是否仍然有意义?

工作流程

  1. 先理解内容,再关注标签。 每个块是什么?导航、主要内容、独立项目、交互式控件?如果意图不明确(例如看起来像按钮的链接),则假设最可能的解读,并说明你假设了哪一种。
  2. 使用下面的清单进行审查。
  3. 按定义的格式回答。

审查清单

文档

  • <!DOCTYPE html>、<html lang="...">、<meta charset="utf-8">、<meta name="viewport">、描述性 <title>(仅当片段是完整文档时)。

地标

  • <header>、<nav>、<main>(每页仅一个可见)、<aside>、<footer>。
  • <section> 用于组织主题内容,通常应包含标题;没有标题时,它可能应该是 <div>。
  • <article> 指独立也有意义的内容(帖子、产品卡片、评论)。
  • 页面上有多个 <nav> → 使用 aria-label 加以区分。

标题

  • 层级不应跳过(h2 → h4 是问题)。
  • 标题描述其所在部分;不要使用标题来使文字变大,也不要用样式化文本代替标题。

交互

  • 页面上的操作 → <button>(在表单内需显式指定 type)。导航到另一个 URL → <a href>。
  • <div onclick>、<span onclick> 和没有 href 的 <a> 是危险信号。
  • 在重建原生元素之前,先考虑使用它们:<details>/<summary>、<dialog>。

表单

  • 每个字段都有关联的 <label>(使用 for/id 或包裹 input)。占位符不能替代标签。
  • 单选/复选框组使用 <fieldset> + <legend>。
  • 适当的 type(email、tel、number、date……)以及在合适的地方使用 autocomplete。

列表和表格

  • 一组项目 → <ul>/<ol>;术语–定义对 → <dl>。
  • <table> 仅用于表格数据,需包含 <caption>、<thead> 和 <th scope>。绝不能用于布局。

媒体

  • <img> 应包含描述其用途的 alt;装饰性图片 → alt=""。
  • 带标题的图片 → <figure> + <figcaption>。

文本

  • 有意义的强调:<strong>/<em>;<b>/<i> 仅用于无重要性含义的样式偏移。
  • 在合适的地方使用 <time datetime>、<blockquote>/<q>、<cite>、<abbr>、<code>/<pre>、<address>。
  • <br> 仅用于内容中的换行(地址、诗歌),而非用于间距。

ARIA

  • 首要规则:如果存在原生元素,则使用它而非 ARIA。
  • 标记冗余 ARIA(<button role="button">、<nav role="navigation">)以及与标签矛盾的 ARIA。

不要过度修正。 当 <div> 和 <span> 仅用于布局或样式时,它们是正确的选择。将每个 <div> 都替换为 <section> 反而会使可访问性树变得更糟。

响应格式(混合语气:直接修复 + 简短原因)

诊断

按影响程度分组的问题列表:

  • 破坏可访问性/可用性 — 阻止某人使用页面的问题(没有焦点的按钮、没有标签的字段、没有 alt 的图片)。
  • 语义不精确 — 虽能工作,但传达错误的结构(跳过的标题、没有标题的 section)。
  • 细节 — 更精细的改进。

每个项目:什么问题 → 应该使用什么。一句话。

修正后的代码

完整的重写 HTML,仅在更改过的部分添加简短注释。

为什么

2 到 5 条简短解释,每条对应一个重要决策,并与浏览器/可访问性树的行为相关联。如果某个概念是核心(例如隐式角色、地标),用具体示例解释一次。

如果代码已经很好,则明确说明,并仅指出真正值得调整的部分。

示例

输入:

<div class="header">
  <div class="logo">商店</div>
  <div class="menu"><a>首页</a><a>产品</a></div>
</div>
<div class="title">促销</div>
<div onclick="buy()">购买</div>

输出(精简版):

诊断

  • 破坏可用性:<div onclick> → <button type="button">;没有 href 的 <a> → 带有 href 的链接。
  • 语义不精确:.header → <header>;.menu → <nav> 配合 <ul>;.title → <h1>;缺少 <main>。

修正后的代码

<header>
  <p class="logo">商店</p>
  <nav aria-label="主菜单">
    <ul>
      <li><a href="/">首页</a></li>
      <li><a href="/products">产品</a></li>
    </ul>
  </nav>
</header>
<main>
  <h1>促销</h1>
  <button type="button" onclick="buy()">购买</button>
</main>

为什么

  • <div> 不在 Tab 键顺序中,且不对 Enter 键做出反应;<button> 自带焦点和键盘支持,并会被宣布为“按钮”。
  • 没有 href 的 <a> 对浏览器而言不是链接:它不获取焦点,也不会出现在屏幕阅读器的链接列表中。
  • <nav> 和 <main> 成为地标:屏幕阅读器用户可以跳转到它们。

来源

当对某条规则有疑问时,在 MDN 或 HTML 生活标准中确认(如果可用文档工具,就使用它),并引用链接。

相关技能