semantic-html
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSemantic HTML
语义化HTML
Write HTML that conveys meaning, serves all users, and respects the web platform.
编写能够传递含义、服务所有用户并遵循Web平台规范的HTML。
When to Use This Skill
适用场景
Use this skill when:
- Creating new components or page sections
- Reviewing markup for accessibility and semantics
- Deciding between native HTML elements and ARIA attributes
- Structuring documents with proper heading hierarchy
- Making interactive elements accessible
- Building forms with proper labelling and error handling
- Creating responsive tables
在以下场景中使用本技能:
- 创建新组件或页面区块
- 审查标记的可访问性与语义化程度
- 选择使用原生HTML元素还是ARIA属性
- 构建具有规范标题层级的文档结构
- 确保交互式元素的可访问性
- 构建带有规范标签和错误处理的表单
- 创建响应式表格
Core Principles
核心原则
Content Realism
内容真实性
Design content is idealized. Real content is messy. Always account for:
- Long sentences and long words
- Images with varying aspect ratios and sizes
- Multi-language support (even if not planned—users can translate via browser)
- Dynamic content that changes in length and structure
Build components that handle real-world content gracefully, not just what looks good in design tools.
设计稿中的内容是理想化的,而真实内容往往杂乱无章。请始终考虑以下情况:
- 长句和长单词
- 不同宽高比和尺寸的图片
- 多语言支持(即使未做规划,用户也可通过浏览器翻译)
- 长度和结构会动态变化的内容
构建能够优雅处理真实内容的组件,而非仅适配设计工具中看起来美观的内容。
Landmarks-First Planning
优先规划地标元素
Before diving into individual components, consider the full page structure. This allows you to:
- Identify key landmarks for assistive technology users
- Plan heading hierarchy across the document
- Make informed decisions about element choice
- Avoid overusing landmarks (which diminishes their usefulness)
在深入开发单个组件之前,先考虑完整的页面结构。这能让你:
- 为辅助技术用户识别关键地标元素
- 规划整个文档的标题层级
- 明智地选择元素类型
- 避免过度使用地标元素(这会降低其效用)
Native Over ARIA
优先使用原生元素而非ARIA
Follow the first rule of ARIA: if a native HTML element provides the semantics and behaviour you need, use it instead of adding ARIA to a generic element.
Red flag: High div count combined with high ARIA count on non-complex components signals reaching for patches rather than foundations.
遵循ARIA的首要规则:如果原生HTML元素能提供你所需的语义和行为,请使用原生元素,而非为通用元素添加ARIA属性。
危险信号: 在非复杂组件中,div元素数量多且ARIA属性数量也多,这表明你在使用补丁而非基础方案。
Separation of Visual and Semantic Hierarchy
视觉层级与语义层级分离
Visual styling and semantic meaning are related but not coupled. CSS classes bridge the gap:
- Use the appropriate heading level based on document structure
- Apply CSS classes to control visual appearance (size, weight, colour)
- Create utility classes like for consistent visual treatment regardless of semantic level
.u-Heading-XXL
视觉样式与语义含义相关但并非绑定关系,可通过CSS类来衔接:
- 根据文档结构选择合适的标题层级
- 使用CSS类控制视觉表现(尺寸、字重、颜色)
- 创建类似的工具类,实现与语义层级无关的统一视觉样式
.u-Heading-XXL
Document Structure
文档结构
Landmark Elements
地标元素
Use landmark elements to convey page structure:
| Element | Use When | Notes |
|---|---|---|
| Page or section header | Can appear multiple times in different contexts |
| Page or section footer | Contact info, copyright, related links |
| Navigation sections | Must be labelled; avoid "navigation" in the label (screen readers announce this) |
| Primary content | Only one per page |
| Tangentially related content | Sidebars, pull quotes, advertising |
| Search functionality | Contains the search form, not the results |
| User input | Only becomes a landmark when labelled via |
| Self-contained content | Would make sense syndicated or standalone |
| Thematic grouping | Only becomes a landmark when labelled |
使用地标元素传递页面结构:
| 元素 | 适用场景 | 说明 |
|---|---|---|
| 页面或区块头部 | 可在不同上下文多次出现 |
| 页面或区块底部 | 包含联系信息、版权声明、相关链接 |
| 导航区块 | 必须添加标签;标签中避免使用"navigation"(屏幕阅读器会自动播报此内容) |
| 主要内容区域 | 每个页面仅能有一个 |
| 次要关联内容 | 侧边栏、引言引用、广告 |
| 搜索功能区域 | 包含搜索表单,而非搜索结果 |
| 用户输入区域 | 仅当通过 |
| 独立内容区域 | 可被联合发布或独立存在的内容 |
| 主题分组区域 | 仅当添加标签后才会成为地标元素 |
The Section Element
Section元素
A without an accessible name behaves like a semantically. When using :
sectiondivsection- Associate it with a heading via
aria-labelledby - This transforms it into a valid landmark region
- If you cannot provide a meaningful label, question whether is the right choice
section
未添加可访问名称的在语义上与无异。使用时:
sectiondivsection- 通过将其与标题关联
aria-labelledby - 这会将其转换为有效的地标区域
- 如果你无法提供有意义的标签,请重新考虑是否应该使用
section
The Article Element
Article元素
Think beyond blog posts. Use for any self-contained content that would make sense on its own:
article- Blog posts and news articles
- Comments on a post
- Product cards in a listing
- Social media posts in a feed
- Forum posts
Test: Would this content make sense if extracted and placed elsewhere with no surrounding context?
不要仅将其用于博客文章。任何可独立存在的内容都可使用:
article- 博客文章和新闻报道
- 帖子评论
- 商品列表中的商品卡片
- 信息流中的社交媒体帖子
- 论坛帖子
测试方法: 如果将此内容提取出来,脱离原有上下文仍有意义,那么就适合使用。
articleThe Address Element
Address元素
Often misunderstood. From the HTML specification:
The address element represents the contact information for its nearest article or body element ancestor.
Use for contact information about the author or owner—not for generic postal addresses. For postal addresses, use a standard or structured markup appropriate to the context.
<p>该元素常被误解。根据HTML规范:
address元素代表其最近的article或body祖先元素的联系信息。
用于展示作者或所有者的联系信息——而非通用邮政地址。对于邮政地址,请使用标准或适合上下文的结构化标记。
<p>Headings
标题
Heading Hierarchy
标题层级
Maintain a logical heading structure:
- One per page (typically the main title)
h1 - Don't skip levels (h1 → h3)
- Headings create an outline—ensure it makes sense when read in sequence
保持逻辑清晰的标题结构:
- 每个页面仅使用一个(通常为主标题)
h1 - 不要跳过层级(如从h1直接跳到h3)
- 标题会构成文档大纲,请确保按顺序阅读时逻辑通顺
Headings in Components
组件中的标题
For reusable components containing headings:
- Make heading level configurable — Components may appear in different contexts
- Provide sensible defaults — Not all content authors understand heading hierarchy
- Consider inheritance — Generic components become specific ones; heading config should flow through
Example pattern:
Card (generic) → heading level configurable, default h3
└─ ProductCard (specific) → inherits config, may set default based on known context
└─ Used in section with h2 → heading level set to h3对于包含标题的可复用组件:
- 让标题层级可配置——组件可能会出现在不同的上下文中
- 提供合理的默认值——并非所有内容作者都了解标题层级
- 考虑继承性——通用组件可变为特定组件;标题配置应能继承
示例模式:
Card(通用组件)→ 标题层级可配置,默认h3
└─ ProductCard(特定组件)→ 继承配置,可根据已知上下文设置默认值
└─ 在包含h2的区块中使用 → 标题层级设为h3Visual Heading Without Semantic Heading
仅视觉样式的标题(非语义化标题)
Sometimes text looks like a heading but shouldn't be one semantically. Use CSS classes to apply heading-like styling without affecting document outline:
html
<p class="u-Heading-L">This looks like a heading</p>有时文本看起来像标题,但在语义上不应作为标题。使用CSS类应用类似标题的样式,同时不影响文档大纲:
html
<p class="u-Heading-L">This looks like a heading</p>Lists
列表
When to Use Lists
何时使用列表
Lists are most useful when knowing the number of items helps the user:
- Navigation menus (how many options?)
- Search results (how many matches?)
- Image galleries (how many images?)
- Steps in a process
Questions to ask:
- Are these items genuinely peers?
- Would removing one make the others feel incomplete?
- Is there an implicit "here are N things" being communicated?
当了解项目数量对用户有帮助时,列表最为有用:
- 导航菜单(有多少个选项?)
- 搜索结果(有多少个匹配项?)
- 图片画廊(有多少张图片?)
- 流程步骤
自问:
- 这些项目是否真正属于同一层级?
- 删除其中一个项目会让其他项目显得不完整吗?
- 是否隐含着“这里有N个内容”的信息?
List Types
列表类型
| Type | Use When | Example |
|---|---|---|
| Unordered collection where count matters | Nav items, search results |
| Sequential steps or ranked items | Recipes, instructions, top-10 lists |
| Term-description pairs | Glossaries, metadata, key-value pairs |
| Toolbar commands | Action buttons, not navigation |
Ordered list attributes: Use for countdown-style lists (e.g., a top 10 listed from 10 to 1). Use to begin numbering from a specific value. Both are native HTML—no JavaScript required.
reversedstart| 类型 | 适用场景 | 示例 |
|---|---|---|
| 项目数量有意义的无序列表 | 导航项、搜索结果 |
| 有序步骤或排名项目 | 食谱、操作指南、十大榜单 |
| 术语-描述对 | 术语表、元数据、键值对 |
| 工具栏命令 | 操作按钮,而非导航 |
有序列表属性: 使用创建倒计时式列表(如从10到1的十大榜单)。使用从特定数字开始编号。这两种都是原生HTML属性——无需JavaScript。
reversedstartDefinition Lists
定义列表
Often overlooked or confused with /. Use for:
detailssummarydl- Glossary definitions
- Metadata display (label: value pairs)
- Any term with one or more descriptions
Note: A single can have multiple elements for multiple related descriptions.
dtdd常被忽视或与/混淆。使用的场景:
detailssummarydl- 术语表定义
- 元数据展示(标签:值对)
- 带有一个或多个描述的术语
注意:单个可对应多个元素,用于多个相关描述。
dtddInteractive Elements
交互式元素
Buttons vs Links
按钮与链接的区别
Traditional rule: Buttons do things, links go places.
Progressive enhancement lens: If a URL provides a meaningful fallback when JavaScript fails, a link is valid even for action-like interactions.
| Interaction | Default Choice | Consider Link When |
|---|---|---|
| Show more content | | URL params could load the content server-side |
| Toggle view (grid/list) | | URL could preserve view preference |
| Copy to clipboard | | Copied content is a shareable URL |
| Tab selection | | URL could load specific tab content |
Key question: What happens when JavaScript fails? If a URL provides graceful degradation, a link may be the better choice.
传统规则: 按钮用于执行操作,链接用于跳转页面。
渐进增强视角: 如果JavaScript失效时,URL能提供有意义的降级方案,那么即使是类操作的交互,使用链接也是合理的。
| 交互类型 | 默认选择 | 考虑使用链接的场景 |
|---|---|---|
| 显示更多内容 | | URL参数可在服务端加载内容时 |
| 切换视图(网格/列表) | | URL可保存视图偏好时 |
| 复制到剪贴板 | | 复制的内容是可分享的URL时 |
| 标签页切换 | | URL可加载特定标签页内容时 |
关键问题: JavaScript失效时会发生什么?如果URL能提供优雅的降级方案,链接可能是更好的选择。
The Details/Summary Pattern
Details/Summary模式
Use for progressive disclosure:
- FAQ sections
- Expandable content sections
- Collapsible navigation
Not a replacement for proper heading structure or definition lists.
用于渐进式展示内容:
- FAQ区块
- 可展开的内容区块
- 可折叠的导航
不要用它替代规范的标题结构或定义列表。
Forms
表单
Grouping with Fieldset/Legend
使用Fieldset/Legend分组
Use and for thematic grouping, not layout:
fieldsetlegend- Address fields
- Personal information sections
- Privacy/consent checkboxes
- Payment details
Benefits:
- Enables progressive disclosure (reveal sections as user completes others)
- Reduces overwhelm (avoids "wall of form fields")
- Provides context for screen reader users
Legends can be visually hidden while still providing accessible names.
使用和进行主题分组,而非布局:
fieldsetlegend- 地址字段
- 个人信息区块
- 隐私/同意复选框
- 支付详情
优势:
- 支持渐进式展示(用户完成部分内容后再显示其他区块)
- 减少用户负担(避免“表单墙”)
- 为屏幕阅读器用户提供上下文
可将Legend视觉隐藏,同时仍保留可访问名称。
Labels
标签
Always use a element. No exceptions.
label- Visually hidden labels are acceptable when design requires it
- Never rely on placeholder text as a label substitute
- Never use when a proper
aria-labelelement workslabel
Why placeholders fail:
- Disappear on input (problematic for cognitive challenges, stress, or distraction)
- Often have poor contrast
- Don't provide persistent identification
务必使用元素。 无例外。
label- 当设计要求时,可使用视觉隐藏的标签
- 永远不要用占位符文本替代标签
- 当合适的元素可用时,永远不要使用
labelaria-label
占位符的缺陷:
- 输入时会消失(对有认知障碍、压力或容易分心的用户不友好)
- 对比度通常较低
- 无法提供持久的标识
Error Messages
错误提示
Current best practice (due to browser support gaps with ):
aria-errormessage- Set on the invalid input
aria-invalid="true" - Associate error message via
aria-describedby - Ensure error message is actionable (state the problem AND guide the fix)
- For dynamic errors (shown on blur), consider on the error container
aria-live
html
<label for="email">Email</label>
<input
type="email"
id="email"
aria-invalid="true"
aria-describedby="email-error"
/>
<p id="email-error" class="error">
Enter a valid email address, like name@example.com
</p>当前最佳实践(因的浏览器支持存在差异):
aria-errormessage- 在无效输入框上设置
aria-invalid="true" - 通过关联错误提示信息
aria-describedby - 确保错误提示具有可操作性(说明问题并指导修正方法)
- 对于动态错误(失去焦点时显示),可考虑在错误容器上使用
aria-live
html
<label for="email">Email</label>
<input
type="email"
id="email"
aria-invalid="true"
aria-describedby="email-error"
/>
<p id="email-error" class="error">
请输入有效的邮箱地址,例如 name@example.com
</p>Tables
表格
When to Use Tables
何时使用表格
Use a table when data has meaningful relationships in both dimensions:
- Data must be presented as rows AND columns
- Clear association between headers and data
- Each row has the same columns
- Within each column, data is of the same type
当数据在两个维度上都有有意义的关联时,使用表格:
- 数据必须以行和列的形式呈现
- 表头与数据之间有明确的关联
- 每行包含相同的列
- 每列的数据类型相同
When NOT to Use Tables
何时不使用表格
- Simple lists (one dimension)
- Key-value pairs (use )
dl - Form layouts
- Hierarchical data (use nested lists)
- 简单列表(仅一个维度)
- 键值对(使用)
dl - 表单布局
- 层级数据(使用嵌套列表)
Table Semantics Baseline
表格语义基础
Always include:
- — Describes the table's purpose
caption - ,
thead,tbody— Structural groupingtfoot - with
th— Identifies header cells and their directionscope
务必包含:
- — 描述表格的用途
caption - ,
thead,tbody— 结构分组tfoot - 带有属性的
scope— 标识表头单元格及其方向th
Responsive Tables
响应式表格
In order of preference:
- Hide non-essential columns — User still gets main takeaways; offer button to show full table
- Horizontal scroll — Preserves semantics but may challenge users with motor difficulties
- Component duplication (cards on mobile) — Last resort; maintain accessibility in both versions
Note: Modern browsers (including Safari) no longer strip table semantics when applying or , opening new responsive possibilities.
display: griddisplay: flex优先顺序:
- 隐藏非必要列 — 用户仍能获取核心信息;提供按钮展示完整表格
- 横向滚动 — 保留语义,但可能对有运动障碍的用户不友好
- 组件复用(移动端使用卡片) — 最后手段;确保两种版本都具备可访问性
注意:现代浏览器(包括Safari)在应用或时,不再剥离表格语义,这为响应式设计提供了新的可能。
display: griddisplay: flexCode Review Checklist
代码审查清单
When reviewing markup, look for:
审查标记时,需关注:
Positive Signals
积极信号
- Landmark elements used appropriately
- Logical heading hierarchy
- Native interactive elements (buttons, links) used correctly
- Forms have proper labels and fieldsets
- Tables have full semantic structure
- ARIA used sparingly and correctly
- 地标元素使用恰当
- 标题层级逻辑清晰
- 原生交互式元素(按钮、链接)使用正确
- 表单具备规范的标签和字段集
- 表格具备完整的语义结构
- ARIA使用谨慎且正确
Warning Signs
警告信号
- High div count in non-complex components
- ARIA attributes compensating for missing native semantics
- Placeholders used as labels
- Heading levels chosen for visual size rather than structure
- Generic elements with click handlers instead of buttons/links
- Tables used for layout
- Missing form labels
- 非复杂组件中div元素数量过多
- 使用ARIA属性弥补缺失的原生语义
- 使用占位符替代标签
- 根据视觉尺寸选择标题层级而非结构
- 为通用元素添加点击事件而非使用按钮/链接
- 使用表格进行布局
- 缺少表单标签
Resources
资源
References
参考资料
See the directory for detailed guidance on specific topics:
references/- — Quick decision frameworks for element selection
element-decision-trees.md - — Component heading patterns and configuration strategies
heading-patterns.md
请查看目录获取特定主题的详细指南:
references/- — 元素选择的快速决策框架
element-decision-trees.md - — 组件标题模式和配置策略
heading-patterns.md