Skip to content

6.2 表格高级特性

关键词: 单元格合并, 表格分组, 响应式表格, 表格可访问性, colspan, rowspan, 表格标题, 表格优化

学习目标

  • 掌握单元格合并的技术和应用场景
  • 学会使用表格分组提高数据组织效率
  • 理解表格可访问性的重要性和实现方法
  • 学会创建响应式表格适应不同设备
  • 掌握表格的高级样式和交互功能

6.2.1 单元格合并

列合并(colspan)

colspan属性用于让单元格横跨多个列,常用于创建表格标题或分组标题:

html
<!-- 基本的列合并 -->
<table>
    <tr>
        <th colspan="3">员工信息统计表</th>
    </tr>
    <tr>
        <th>姓名</th>
        <th>部门</th>
        <th>职位</th>
    </tr>
    <tr>
        <td>张三</td>
        <td>技术部</td>
        <td>前端工程师</td>
    </tr>
    <tr>
        <td>李四</td>
        <td>设计部</td>
        <td>UI设计师</td>
    </tr>
</table>

行合并(rowspan)

rowspan属性用于让单元格纵跨多个行,适用于相同数据的合并显示:

html
<!-- 基本的行合并 -->
<table>
    <tr>
        <th>部门</th>
        <th>姓名</th>
        <th>职位</th>
    </tr>
    <tr>
        <td rowspan="2">技术部</td>
        <td>张三</td>
        <td>前端工程师</td>
    </tr>
    <tr>
        <td>李四</td>
        <td>后端工程师</td>
    </tr>
    <tr>
        <td rowspan="2">设计部</td>
        <td>王五</td>
        <td>UI设计师</td>
    </tr>
    <tr>
        <td>赵六</td>
        <td>UX设计师</td>
    </tr>
</table>

复杂的单元格合并

结合使用colspanrowspan创建复杂的表格结构:

html
<!-- 复杂的单元格合并示例 -->
<table>
    <caption>公司季度绩效报告</caption>
    <thead>
        <tr>
            <th rowspan="2">部门</th>
            <th colspan="4">季度业绩</th>
            <th rowspan="2">年度总计</th>
        </tr>
        <tr>
            <th>Q1</th>
            <th>Q2</th>
            <th>Q3</th>
            <th>Q4</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th>销售部</th>
            <td>¥500,000</td>
            <td>¥600,000</td>
            <td>¥750,000</td>
            <td>¥800,000</td>
            <td>¥2,650,000</td>
        </tr>
        <tr>
            <th>市场部</th>
            <td>¥200,000</td>
            <td>¥250,000</td>
            <td>¥300,000</td>
            <td>¥350,000</td>
            <td>¥1,100,000</td>
        </tr>
        <tr>
            <th>技术部</th>
            <td>¥300,000</td>
            <td>¥350,000</td>
            <td>¥400,000</td>
            <td>¥450,000</td>
            <td>¥1,500,000</td>
        </tr>
    </tbody>
    <tfoot>
        <tr>
            <th>总计</th>
            <td>¥1,000,000</td>
            <td>¥1,200,000</td>
            <td>¥1,450,000</td>
            <td>¥1,600,000</td>
            <td>¥5,250,000</td>
        </tr>
    </tfoot>
</table>

合并单元格的注意事项

在使用单元格合并时,需要注意以下几点:

html
<!-- 正确的合并示例 -->
<table>
    <tr>
        <th colspan="2">联系信息</th>
        <th colspan="2">工作信息</th>
    </tr>
    <tr>
        <th>电话</th>
        <th>邮箱</th>
        <th>部门</th>
        <th>职位</th>
    </tr>
    <tr>
        <td>13800138000</td>
        <td>zhang@example.com</td>
        <td>技术部</td>
        <td>工程师</td>
    </tr>
</table>

6.2.2 表格标题和说明

使用caption元素

caption元素为表格提供标题和说明,是表格可访问性的重要组成部分:

html
<!-- 详细的表格标题 -->
<table>
    <caption>
        <h3>2024年第一季度销售报告</h3>
        <p>数据统计时间:2024年1月1日 - 2024年3月31日</p>
        <p>数据来源:销售管理系统</p>
    </caption>
    <thead>
        <tr>
            <th>产品类别</th>
            <th>销售数量</th>
            <th>销售金额</th>
            <th>市场份额</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>笔记本电脑</td>
            <td>1,250台</td>
            <td>¥8,750,000</td>
            <td>35%</td>
        </tr>
        <tr>
            <td>台式电脑</td>
            <td>800台</td>
            <td>¥4,800,000</td>
            <td>25%</td>
        </tr>
        <tr>
            <td>智能手机</td>
            <td>2,100台</td>
            <td>¥6,300,000</td>
            <td>40%</td>
        </tr>
    </tbody>
</table>

表格摘要信息

为复杂表格添加摘要信息,帮助用户理解表格内容:

html
<!-- 带摘要信息的表格 -->
<table>
    <caption>
        <strong>员工薪资统计表</strong>
        <details>
            <summary>表格说明</summary>
            <p>本表格显示了各部门员工的薪资分布情况,包括基本工资、绩效奖金和福利补贴。</p>
            <p>数据更新频率:每月更新一次</p>
            <p>最后更新时间:2024年1月31日</p>
        </details>
    </caption>
    <thead>
        <tr>
            <th>部门</th>
            <th>基本工资</th>
            <th>绩效奖金</th>
            <th>福利补贴</th>
            <th>总计</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>技术部</td>
            <td>¥12,000</td>
            <td>¥3,000</td>
            <td>¥2,000</td>
            <td>¥17,000</td>
        </tr>
        <tr>
            <td>设计部</td>
            <td>¥10,000</td>
            <td>¥2,500</td>
            <td>¥1,800</td>
            <td>¥14,300</td>
        </tr>
    </tbody>
</table>

表格图例和注释

html
<!-- 带图例的表格 -->
<table>
    <caption>项目进度追踪表</caption>
    <thead>
        <tr>
            <th>项目名称</th>
            <th>负责人</th>
            <th>开始日期</th>
            <th>预计完成</th>
            <th>状态</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>网站重构</td>
            <td>张三</td>
            <td>2024-01-15</td>
            <td>2024-03-15</td>
            <td class="status-progress">进行中</td>
        </tr>
        <tr>
            <td>移动端应用</td>
            <td>李四</td>
            <td>2024-02-01</td>
            <td>2024-04-01</td>
            <td class="status-planning">计划中</td>
        </tr>
        <tr>
            <td>数据分析系统</td>
            <td>王五</td>
            <td>2024-01-01</td>
            <td>2024-02-28</td>
            <td class="status-completed">已完成</td>
        </tr>
    </tbody>
</table>

<!-- 表格图例 -->
<div class="table-legend">
    <h4>状态说明:</h4>
    <ul>
        <li><span class="status-completed">已完成</span> - 项目已完成并交付</li>
        <li><span class="status-progress">进行中</span> - 项目正在开发中</li>
        <li><span class="status-planning">计划中</span> - 项目处于规划阶段</li>
    </ul>
</div>

6.2.3 表格分组

使用多个tbody

将相关的数据行分组到不同的tbody中:

html
<!-- 多个tbody分组 -->
<table>
    <caption>员工按部门分组统计</caption>
    <thead>
        <tr>
            <th>姓名</th>
            <th>职位</th>
            <th>工作年限</th>
            <th>薪资</th>
        </tr>
    </thead>
    
    <!-- 技术部 -->
    <tbody>
        <tr class="group-header">
            <td colspan="4"><strong>技术部</strong></td>
        </tr>
        <tr>
            <td>张三</td>
            <td>前端工程师</td>
            <td>3年</td>
            <td>¥15,000</td>
        </tr>
        <tr>
            <td>李四</td>
            <td>后端工程师</td>
            <td>5年</td>
            <td>¥18,000</td>
        </tr>
        <tr>
            <td>王五</td>
            <td>全栈工程师</td>
            <td>4年</td>
            <td>¥16,000</td>
        </tr>
    </tbody>
    
    <!-- 设计部 -->
    <tbody>
        <tr class="group-header">
            <td colspan="4"><strong>设计部</strong></td>
        </tr>
        <tr>
            <td>赵六</td>
            <td>UI设计师</td>
            <td>2年</td>
            <td>¥12,000</td>
        </tr>
        <tr>
            <td>钱七</td>
            <td>UX设计师</td>
            <td>3年</td>
            <td>¥13,000</td>
        </tr>
    </tbody>
    
    <!-- 市场部 -->
    <tbody>
        <tr class="group-header">
            <td colspan="4"><strong>市场部</strong></td>
        </tr>
        <tr>
            <td>孙八</td>
            <td>市场专员</td>
            <td>2年</td>
            <td>¥10,000</td>
        </tr>
        <tr>
            <td>李九</td>
            <td>市场经理</td>
            <td>6年</td>
            <td>¥20,000</td>
        </tr>
    </tbody>
</table>

表格列组(colgroup)

使用colgroupcol元素为表格列定义样式和属性:

html
<!-- 使用colgroup的表格 -->
<table>
    <caption>产品销售数据表</caption>
    <colgroup>
        <col class="product-name">
        <col class="price" span="2">
        <col class="quantity">
        <col class="total">
    </colgroup>
    <thead>
        <tr>
            <th>产品名称</th>
            <th>原价</th>
            <th>折扣价</th>
            <th>销售数量</th>
            <th>总金额</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>笔记本电脑</td>
            <td>¥8,000</td>
            <td>¥7,200</td>
            <td>50台</td>
            <td>¥360,000</td>
        </tr>
        <tr>
            <td>智能手机</td>
            <td>¥4,000</td>
            <td>¥3,600</td>
            <td>100台</td>
            <td>¥360,000</td>
        </tr>
    </tbody>
</table>

分组样式设置

css
/* 表格分组样式 */
.group-header td {
    background-color: #e9ecef;
    font-weight: bold;
    border-top: 2px solid #dee2e6;
    padding: 0.5rem;
}

/* 列组样式 */
.product-name {
    width: 30%;
    background-color: #f8f9fa;
}

.price {
    width: 15%;
    text-align: right;
}

.quantity {
    width: 15%;
    text-align: center;
}

.total {
    width: 20%;
    text-align: right;
    font-weight: bold;
}

6.2.4 表格响应式处理

基本响应式策略

为小屏幕设备优化表格显示:

css
/* 响应式表格样式 */
.responsive-table {
    width: 100%;
    border-collapse: collapse;
    margin: 1rem 0;
}

.responsive-table th,
.responsive-table td {
    padding: 0.75rem;
    text-align: left;
    border-bottom: 1px solid #ddd;
}

/* 平板设备 */
@media (max-width: 768px) {
    .responsive-table {
        font-size: 0.9rem;
    }
    
    .responsive-table th,
    .responsive-table td {
        padding: 0.5rem;
    }
}

/* 手机设备 */
@media (max-width: 480px) {
    .responsive-table {
        font-size: 0.8rem;
    }
    
    .responsive-table th,
    .responsive-table td {
        padding: 0.25rem;
    }
    
    /* 隐藏不重要的列 */
    .responsive-table .hide-mobile {
        display: none;
    }
}

水平滚动响应式

html
<!-- 水平滚动的响应式表格 -->
<div class="table-responsive">
    <table class="responsive-table">
        <thead>
            <tr>
                <th>产品名称</th>
                <th>型号</th>
                <th>价格</th>
                <th class="hide-mobile">库存</th>
                <th class="hide-mobile">供应商</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>笔记本电脑</td>
                <td>ThinkPad X1</td>
                <td>¥12,000</td>
                <td class="hide-mobile">50</td>
                <td class="hide-mobile">联想</td>
                <td>
                    <button>编辑</button>
                    <button>删除</button>
                </td>
            </tr>
            <tr>
                <td>智能手机</td>
                <td>iPhone 15</td>
                <td>¥8,000</td>
                <td class="hide-mobile">30</td>
                <td class="hide-mobile">苹果</td>
                <td>
                    <button>编辑</button>
                    <button>删除</button>
                </td>
            </tr>
        </tbody>
    </table>
</div>
css
/* 水平滚动样式 */
.table-responsive {
    overflow-x: auto;
    margin: 1rem 0;
}

@media (max-width: 768px) {
    .table-responsive {
        border: 1px solid #ddd;
        border-radius: 4px;
    }
}

卡片式响应式布局

html
<!-- 卡片式响应式表格 -->
<div class="table-container">
    <table class="card-table">
        <thead class="desktop-only">
            <tr>
                <th>姓名</th>
                <th>职位</th>
                <th>部门</th>
                <th>邮箱</th>
            </tr>
        </thead>
        <tbody>
            <tr class="table-row">
                <td data-label="姓名">张三</td>
                <td data-label="职位">前端工程师</td>
                <td data-label="部门">技术部</td>
                <td data-label="邮箱">zhangsan@example.com</td>
            </tr>
            <tr class="table-row">
                <td data-label="姓名">李四</td>
                <td data-label="职位">UI设计师</td>
                <td data-label="部门">设计部</td>
                <td data-label="邮箱">lisi@example.com</td>
            </tr>
        </tbody>
    </table>
</div>
css
/* 卡片式响应式样式 */
@media (max-width: 768px) {
    .desktop-only {
        display: none;
    }
    
    .card-table,
    .card-table tbody,
    .card-table tr,
    .card-table td {
        display: block;
    }
    
    .table-row {
        border: 1px solid #ddd;
        border-radius: 8px;
        padding: 1rem;
        margin-bottom: 1rem;
        background: white;
    }
    
    .table-row td {
        border: none;
        padding: 0.5rem 0;
        text-align: left;
    }
    
    .table-row td:before {
        content: attr(data-label) ": ";
        font-weight: bold;
        color: #666;
    }
}

6.2.5 表格可访问性

标题和数据关联

使用idheaders属性建立标题与数据的关联:

html
<!-- 可访问性优化的表格 -->
<table>
    <caption>员工绩效评估表</caption>
    <thead>
        <tr>
            <th id="name">姓名</th>
            <th id="department">部门</th>
            <th id="performance">绩效评分</th>
            <th id="bonus">奖金</th>
            <th id="comments">评语</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td headers="name">张三</td>
            <td headers="department">技术部</td>
            <td headers="performance">90分</td>
            <td headers="bonus">¥5,000</td>
            <td headers="comments">表现优秀,技术能力强</td>
        </tr>
        <tr>
            <td headers="name">李四</td>
            <td headers="department">设计部</td>
            <td headers="performance">85分</td>
            <td headers="bonus">¥3,000</td>
            <td headers="comments">设计能力良好,需提升沟通</td>
        </tr>
    </tbody>
</table>

作用域和分组

使用scope属性明确标题的作用范围:

html
<!-- 使用scope属性的复杂表格 -->
<table>
    <caption>2024年各部门季度业绩统计</caption>
    <thead>
        <tr>
            <th rowspan="2" scope="col">部门</th>
            <th colspan="4" scope="colgroup">季度业绩</th>
        </tr>
        <tr>
            <th scope="col">Q1</th>
            <th scope="col">Q2</th>
            <th scope="col">Q3</th>
            <th scope="col">Q4</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th scope="row">销售部</th>
            <td>¥500,000</td>
            <td>¥600,000</td>
            <td>¥750,000</td>
            <td>¥800,000</td>
        </tr>
        <tr>
            <th scope="row">市场部</th>
            <td>¥200,000</td>
            <td>¥250,000</td>
            <td>¥300,000</td>
            <td>¥350,000</td>
        </tr>
    </tbody>
</table>

键盘导航支持

html
<!-- 支持键盘导航的表格 -->
<table role="table" aria-label="产品库存表">
    <thead>
        <tr role="row">
            <th role="columnheader" tabindex="0">产品名称</th>
            <th role="columnheader" tabindex="0">库存数量</th>
            <th role="columnheader" tabindex="0">状态</th>
        </tr>
    </thead>
    <tbody>
        <tr role="row">
            <td role="cell" tabindex="0">笔记本电脑</td>
            <td role="cell" tabindex="0">50</td>
            <td role="cell" tabindex="0">充足</td>
        </tr>
        <tr role="row">
            <td role="cell" tabindex="0">智能手机</td>
            <td role="cell" tabindex="0">5</td>
            <td role="cell" tabindex="0">库存不足</td>
        </tr>
    </tbody>
</table>
css
/* 键盘焦点样式 */
table th:focus,
table td:focus {
    outline: 2px solid #007bff;
    outline-offset: -2px;
    background-color: #e7f3ff;
}

/* 屏幕阅读器文本 */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

本节要点回顾

  • 单元格合并:使用colspan和rowspan创建复杂的表格结构
  • 表格分组:使用多个tbody和colgroup组织表格数据
  • 响应式设计:通过CSS媒体查询和布局技术优化移动端显示
  • 可访问性优化:使用语义化属性和ARIA标签提高表格可访问性
  • 高级样式:结合CSS创建美观且功能丰富的表格

相关学习资源

常见问题FAQ

Q: 单元格合并时如何避免表格结构混乱?

A: 在使用colspan和rowspan时,要仔细计算每行的单元格总数,确保保持一致。建议先画出表格草图,明确每个单元格的位置和跨度。

Q: 如何让表格在移动设备上有更好的用户体验?

A: 可以使用多种策略:隐藏不重要的列、使用水平滚动、将表格转换为卡片式布局,或者提供数据的替代展示方式。

Q: 什么是表格的可访问性,为什么重要?

A: 表格可访问性是指让视觉障碍用户能够通过屏幕阅读器理解表格内容。通过使用语义化标签、scope属性和ARIA标签,可以让辅助技术正确解读表格结构。

Q: 如何优化大型表格的性能?

A: 可以通过分页显示、虚拟滚动、延迟加载、固定表头等技术来优化大型表格的性能。避免一次性渲染过多数据。

Q: 表格排序和筛选功能如何实现?

A: 可以使用JavaScript实现表格的排序和筛选功能,或者使用现成的表格库如DataTables。同时要注意保持可访问性和响应式设计。


下一节预览:下一节我们将学习第6章第3节 - 表格样式与交互,重点介绍表格的CSS样式设计和JavaScript交互功能。