课表用<table>必须写对三处结构:<thead>首行全用<th>且首单元格留空、加scope="col";<tbody>每行首单元格用<th scope="row">;所有行单元格总数(含合并后)须等于表头<th>数量。

用 <table> 做课表,必须写对的三处结构
直接套用 <table> 很容易出错,不是样式不对,而是语义崩了——屏幕阅读器读不出来“第3节周三上高数”,浏览器也难自动适配。关键不在边框粗细,而在三处结构是否合规:
-
<thead>里第一行必须用<th>,且首单元格留空(对应节次列),后续每个<th>写“周一”“周二”…并加scope="col" -
<tbody>每行第一个单元格必须是<th scope="row">,比如<th scope="row">第1–2节</th>,不能用<td> - 所有行的单元格总数(含
rowspan/colspan合并后)必须严格等于表头<th>数量,否则表格渲染会错位或被截断
rowspan 和 colspan 合并单元格的常见翻车点
跨节次课程(如连上两节)必须用 rowspan,但多数人漏掉配套动作:下一行对应位置必须跳过该 <td>,否则视觉和 DOM 结构都会重复。例如“周三第2–3节上 C 语言”,正确写法是:
<tr> <th scope="row">第2节</th> <td></td> <td></td> <td rowspan="2">C语言</td> <td></td> <td></td> </tr> <tr> <th scope="row">第3节</th> <td></td> <td></td> <!-- 这里不写 td!否则 rowspan 失效 --> <td></td> <td></td> </tr>
注意:rowspan="2" 表示占两行,那下一行同列就不能再放 <td>;colspan 同理,横向合并后,右侧相邻单元格要整体右移一格。
CSS 控制课表可读性比美化更重要
很多人花时间调圆角、渐变色,结果在手机上文字挤成一团、节次列看不清。优先级应该是:
立即学习“前端免费学习笔记(深入)”;
- 强制固定列宽:给节次列(第一列)设
width: 80px,其余列用width: 1fr或具体像素值,避免内容撑开破坏网格 - 禁用默认折叠:
table { table-layout: fixed; },否则长课程名会把整列拉宽,其他列被压缩 - 垂直居中+最小高度:
td, th { vertical-align: middle; min-height: 60px; },防止单字课程和多行课程高度不一致 - 小屏适配底线:用
@media (max-width: 768px)把table包进<div style="overflow-x: auto">,别让表格被裁掉
什么时候不该用 <table>?
如果你的课表要满足以下任一条件,<table> 就不是最佳选择:
- 需要课程块跨天(如“周二下午–周三上午”的实训课)——
rowspan/colspan无法跨<tr>边界 - 要响应式地把周课表变成日视图(按天纵向滚动)——
<table>的行列结构硬编码,切换成本高 - 课程信息带状态(如“已签到”“作业待交”)需频繁 JS 更新——
<table>DOM 操作比<div>+ Grid 慢,重绘范围大
这些场景下,display: grid 配合动态生成的 grid-column/grid-row 更可控,哪怕多写几行 CSS,也比后期修 <table> 的嵌套 bug 省力。



















