应使用包裹单门课程模块,因其语义化表达独立主题内容,需配~标题;课程时间须用标记,分类导航用并限2–3个,动态状态用实时提示。

用 包裹单门课程模块,别套
教育网站的课程表不是表格数据,而是语义化的内容分组。每门课(含标题、简介、时间、教师、报名按钮)应独立为一个逻辑单元, 正是为此设计的。用 套一层再加 class="course-item" 会丢失结构信息,影响屏幕阅读器识别和 SEO。
常见错误:把整张课程表塞进一个 ,或把课程时间单独提成 ——这违反“主题独立性”原则。
-
必须有明确的 ~ 作为标题,不能空着
- 如果课程有子模块(如“课前准备”“配套资料”),可用嵌套
,但层级不超过两层
- 避免在
内再塞一个语义更强的标签(如 表示可独立分发的课程讲义)
课程时间用 标签,别只写纯文本
课程开始时间、持续时长、更新日期这些机器可读的时间信息,必须用 包裹,并提供 datetime 属性。搜索引擎和日历工具依赖这个字段提取事件;纯文本如“每周三 19:00–20:30”对爬虫毫无意义。
错误示例:开课时间:2024-09-10
立即学习“前端免费学习笔记(深入)”;
→ 无法被解析为日期
- 课程固定时段用
–
- 具体开课日用
- 持续周期写成
(ISO 8601 持续时间格式)
课程分类导航用 ,但别滥用
顶部课程类别栏(如“编程|设计|语言|考试”)或侧边难度筛选(“入门|进阶|实战”)属于站点级导航,适合用 。但每门课内部的“上一节|下一节”按钮不是 的使用场景——那是页面内跳转,应放在 或用 更合适。
容易踩的坑:给轮播图下方的课程标签云也套 ,导致辅助技术误判为导航入口。
- 一个页面最多 2–3 个
,用 aria-label 区分用途,例如
- 响应式折叠菜单需确保展开后仍保留在
内,不能动态移出 DOM
- 移动端点击切换分类时,焦点管理要跟上,否则键盘用户会迷失
课程状态(已满/进行中/已结束)用 + ARIA 实时提示
状态变化(如“剩余名额:3”变成“已满”)不是静态文案,而是需要主动通知用户的动态反馈。用 语义化包裹,并配合 aria-live="polite" 让屏幕阅读器自动播报,比单纯改文字更可靠。
注意:不要用 + role="status" 替代 ,前者缺乏表单关联语义,在复杂课程表中易与表单控件混淆。
- 状态变更必须通过 JS 修改
的 textContent,而非 innerHTML(防 XSS)
- 如果状态依赖异步加载(如实时查询余量),要在
fetch 成功后立即更新 ,不要等整个模块重绘
- “已结束”类状态建议加
aria-disabled="true" 并视觉置灰,双重提示不可操作
课程表结构真正的难点不在标签选择,而在内容粒度判断:什么时候该拆成两个 ,什么时候该合并进一个 ; 的 datetime 值是否覆盖所有用户时区场景——这些没法靠语法检查器发现,得对照真实用户动线反复验证。
教育网站的课程表不是表格数据,而是语义化的内容分组。每门课(含标题、简介、时间、教师、报名按钮)应独立为一个逻辑单元, 常见错误:把整张课程表塞进一个 课程开始时间、持续时长、更新日期这些机器可读的时间信息,必须用 错误示例: 开课时间:2024-09-10 立即学习“前端免费学习笔记(深入)”; 顶部课程类别栏(如“编程|设计|语言|考试”)或侧边难度筛选(“入门|进阶|实战”)属于站点级导航,适合用 容易踩的坑:给轮播图下方的课程标签云也套 状态变化(如“剩余名额:3”变成“已满”)不是静态文案,而是需要主动通知用户的动态反馈。用 注意:不要用 正是为此设计的。用 class="course-item" 会丢失结构信息,影响屏幕阅读器识别和 SEO。
,或把课程时间单独提成 ——这违反“主题独立性”原则。
必须有明确的 ~ 作为标题,不能空着,但层级不超过两层 内再塞一个语义更强的标签(如 表示可独立分发的课程讲义)课程时间用
标签,别只写纯文本 包裹,并提供 datetime 属性。搜索引擎和日历工具依赖这个字段提取事件;纯文本如“每周三 19:00–20:30”对爬虫毫无意义。 → 无法被解析为日期
–
(ISO 8601 持续时间格式)课程分类导航用
,但别滥用。但每门课内部的“上一节|下一节”按钮不是 的使用场景——那是页面内跳转,应放在 或用 更合适。,导致辅助技术误判为导航入口。
,用 aria-label 区分用途,例如
内,不能动态移出 DOM课程状态(已满/进行中/已结束)用
+ ARIA 实时提示 语义化包裹,并配合 aria-live="polite" 让屏幕阅读器自动播报,比单纯改文字更可靠。 + role="status" 替代 ,前者缺乏表单关联语义,在复杂课程表中易与表单控件混淆。
课程表结构真正的难点不在标签选择,而在内容粒度判断:什么时候该拆成两个 的 textContent,而非 innerHTML(防 XSS)fetch 成功后立即更新 ,不要等整个模块重绘
aria-disabled="true" 并视觉置灰,双重提示不可操作,什么时候该合并进一个 ; 的 datetime 值是否覆盖所有用户时区场景——这些没法靠语法检查器发现,得对照真实用户动线反复验证。











