Skip to content

HTML 表格

什么是HTML表格

HTML表格用于显示行和列中的数据,是展示结构化信息的理想方式。表格由行、列和单元格组成,能够清晰地组织和呈现数据。

基本表格结构

基本语法

html
<table>
    <tr>
        <th>表头1</th>
        <th>表头2</th>
    </tr>
    <tr>
        <td>数据1</td>
        <td>数据2</td>
    </tr>
</table>

基础标签说明

  • <table>: 表格容器
  • <tr>: 表格行 (table row)
  • <th>: 表头单元格 (table header)
  • <td>: 数据单元格 (table data)

简单表格示例

基本表格

html
<table>
    <tr>
        <th>姓名</th>
        <th>年龄</th>
        <th>职业</th>
    </tr>
    <tr>
        <td>张三</td>
        <td>25</td>
        <td>程序员</td>
    </tr>
    <tr>
        <td>李四</td>
        <td>30</td>
        <td>设计师</td>
    </tr>
    <tr>
        <td>王五</td>
        <td>28</td>
        <td>产品经理</td>
    </tr>
</table>

带样式的表格

html
<style>
table {
    border-collapse: collapse;
    width: 100%;
    margin: 20px 0;
}

th, td {
    border: 1px solid #ddd;
    padding: 12px;
    text-align: left;
}

th {
    background-color: #f2f2f2;
    font-weight: bold;
}

tr:nth-child(even) {
    background-color: #f9f9f9;
}

tr:hover {
    background-color: #f5f5f5;
}
</style>

<table>
    <tr>
        <th>产品名称</th>
        <th>价格</th>
        <th>库存</th>
        <th>状态</th>
    </tr>
    <tr>
        <td>iPhone 15</td>
        <td>¥5999</td>
        <td>150</td>
        <td>有货</td>
    </tr>
    <tr>
        <td>MacBook Pro</td>
        <td>¥12999</td>
        <td>85</td>
        <td>有货</td>
    </tr>
    <tr>
        <td>iPad Air</td>
        <td>¥3999</td>
        <td>0</td>
        <td>缺货</td>
    </tr>
</table>

表格结构化标签

完整的表格结构

html
<table>
    <caption>2024年第一季度销售报告</caption>
    
    <thead>
        <tr>
            <th>月份</th>
            <th>销售额</th>
            <th>增长率</th>
        </tr>
    </thead>
    
    <tbody>
        <tr>
            <td>1月</td>
            <td>¥150,000</td>
            <td>+12%</td>
        </tr>
        <tr>
            <td>2月</td>
            <td>¥180,000</td>
            <td>+20%</td>
        </tr>
        <tr>
            <td>3月</td>
            <td>¥200,000</td>
            <td>+11%</td>
        </tr>
    </tbody>
    
    <tfoot>
        <tr>
            <td><strong>总计</strong></td>
            <td><strong>¥530,000</strong></td>
            <td><strong>+14.3%</strong></td>
        </tr>
    </tfoot>
</table>

结构标签说明

  • <caption>: 表格标题
  • <thead>: 表格头部
  • <tbody>: 表格主体
  • <tfoot>: 表格脚部

单元格合并

列合并 (colspan)

html
<table>
    <tr>
        <th>产品类别</th>
        <th colspan="2">销售数据</th>
    </tr>
    <tr>
        <td>手机</td>
        <td>数量</td>
        <td>金额</td>
    </tr>
    <tr>
        <td>iPhone</td>
        <td>100台</td>
        <td>¥599,900</td>
    </tr>
    <tr>
        <td>Android</td>
        <td>150台</td>
        <td>¥450,000</td>
    </tr>
</table>

行合并 (rowspan)

html
<table>
    <tr>
        <th>部门</th>
        <th>员工</th>
        <th>职位</th>
    </tr>
    <tr>
        <td rowspan="3">技术部</td>
        <td>张三</td>
        <td>前端工程师</td>
    </tr>
    <tr>
        <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>

复杂合并示例

html
<style>
.complex-table {
    border-collapse: collapse;
    width: 100%;
}

.complex-table th,
.complex-table td {
    border: 1px solid #333;
    padding: 8px;
    text-align: center;
}

.complex-table th {
    background-color: #f0f8ff;
    font-weight: bold;
}

.highlight {
    background-color: #fffacd;
}
</style>

<table class="complex-table">
    <caption>公司组织架构表</caption>
    <thead>
        <tr>
            <th colspan="4">ABC科技公司</th>
        </tr>
        <tr>
            <th>部门</th>
            <th>团队</th>
            <th>姓名</th>
            <th>职位</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td rowspan="4" class="highlight">研发部</td>
            <td rowspan="2">前端团队</td>
            <td>张三</td>
            <td>前端主管</td>
        </tr>
        <tr>
            <td>李四</td>
            <td>前端工程师</td>
        </tr>
        <tr>
            <td rowspan="2">后端团队</td>
            <td>王五</td>
            <td>后端主管</td>
        </tr>
        <tr>
            <td>赵六</td>
            <td>后端工程师</td>
        </tr>
        <tr>
            <td rowspan="2" class="highlight">市场部</td>
            <td rowspan="2">销售团队</td>
            <td>钱七</td>
            <td>销售经理</td>
        </tr>
        <tr>
            <td>孙八</td>
            <td>销售专员</td>
        </tr>
    </tbody>
</table>

表格样式设计

基础样式

html
<style>
/* 基本表格样式 */
.basic-table {
    width: 100%;
    border-collapse: collapse;
    margin: 20px 0;
    font-size: 16px;
    font-family: Arial, sans-serif;
}

.basic-table th,
.basic-table td {
    padding: 15px;
    text-align: left;
    border: 1px solid #ddd;
}

.basic-table th {
    background-color: #f4f4f4;
    font-weight: bold;
    color: #333;
}

.basic-table tbody tr:nth-child(even) {
    background-color: #f9f9f9;
}

.basic-table tbody tr:hover {
    background-color: #f0f8ff;
}
</style>

现代风格表格

html
<style>
.modern-table {
    width: 100%;
    border-collapse: collapse;
    margin: 25px 0;
    font-size: 0.9em;
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
}

.modern-table thead tr {
    background-color: #007acc;
    color: #ffffff;
    text-align: left;
}

.modern-table th,
.modern-table td {
    padding: 15px 20px;
    border: none;
}

.modern-table tbody tr {
    border-bottom: 1px solid #dddddd;
}

.modern-table tbody tr:nth-of-type(even) {
    background-color: #f3f3f3;
}

.modern-table tbody tr:last-of-type {
    border-bottom: 2px solid #007acc;
}

.modern-table tbody tr:hover {
    background-color: #f1f1f1;
    transform: scale(1.01);
    transition: all 0.2s ease;
}
</style>

<table class="modern-table">
    <thead>
        <tr>
            <th>用户ID</th>
            <th>用户名</th>
            <th>邮箱</th>
            <th>注册日期</th>
            <th>状态</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>001</td>
            <td>张三</td>
            <td>zhangsan@email.com</td>
            <td>2024-01-15</td>
            <td><span class="status active">活跃</span></td>
        </tr>
        <tr>
            <td>002</td>
            <td>李四</td>
            <td>lisi@email.com</td>
            <td>2024-01-20</td>
            <td><span class="status inactive">禁用</span></td>
        </tr>
        <tr>
            <td>003</td>
            <td>王五</td>
            <td>wangwu@email.com</td>
            <td>2024-02-01</td>
            <td><span class="status pending">待验证</span></td>
        </tr>
    </tbody>
</table>

<style>
.status {
    padding: 5px 10px;
    border-radius: 15px;
    color: white;
    font-size: 12px;
    font-weight: bold;
}

.status.active {
    background-color: #28a745;
}

.status.inactive {
    background-color: #dc3545;
}

.status.pending {
    background-color: #ffc107;
    color: #333;
}
</style>

响应式表格

html
<style>
.responsive-table {
    width: 100%;
    border-collapse: collapse;
    margin: 20px 0;
}

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

.responsive-table th {
    background-color: #f8f9fa;
    position: sticky;
    top: 0;
}

/* 响应式处理 */
@media screen and (max-width: 768px) {
    .responsive-table {
        font-size: 14px;
    }
    
    .responsive-table th,
    .responsive-table td {
        padding: 8px 4px;
    }
    
    /* 隐藏不重要的列 */
    .responsive-table .hide-mobile {
        display: none;
    }
}

@media screen and (max-width: 480px) {
    .responsive-table {
        font-size: 12px;
    }
    
    /* 卡片式布局 */
    .responsive-table,
    .responsive-table thead,
    .responsive-table tbody,
    .responsive-table th,
    .responsive-table td,
    .responsive-table tr {
        display: block;
    }
    
    .responsive-table thead tr {
        position: absolute;
        top: -9999px;
        left: -9999px;
    }
    
    .responsive-table tr {
        border: 1px solid #ccc;
        margin-bottom: 10px;
        padding: 10px;
        border-radius: 5px;
    }
    
    .responsive-table td {
        border: none;
        position: relative;
        padding-left: 50%;
    }
    
    .responsive-table td:before {
        content: attr(data-label) ": ";
        position: absolute;
        left: 6px;
        width: 45%;
        padding-right: 10px;
        white-space: nowrap;
        font-weight: bold;
    }
}
</style>

<table class="responsive-table">
    <thead>
        <tr>
            <th>姓名</th>
            <th>职位</th>
            <th class="hide-mobile">部门</th>
            <th>工资</th>
            <th class="hide-mobile">入职日期</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td data-label="姓名">张三</td>
            <td data-label="职位">前端工程师</td>
            <td data-label="部门" class="hide-mobile">技术部</td>
            <td data-label="工资">¥12,000</td>
            <td data-label="入职日期" class="hide-mobile">2023-03-15</td>
        </tr>
        <tr>
            <td data-label="姓名">李四</td>
            <td data-label="职位">产品经理</td>
            <td data-label="部门" class="hide-mobile">产品部</td>
            <td data-label="工资">¥15,000</td>
            <td data-label="入职日期" class="hide-mobile">2022-11-20</td>
        </tr>
    </tbody>
</table>

表格的可访问性

语义化表格

html
<table>
    <caption>
        <strong>2024年销售业绩报表</strong>
        <p>按月份统计的销售数据和同比增长情况</p>
    </caption>
    
    <thead>
        <tr>
            <th scope="col">月份</th>
            <th scope="col">销售额(万元)</th>
            <th scope="col">同比增长</th>
            <th scope="col">环比增长</th>
        </tr>
    </thead>
    
    <tbody>
        <tr>
            <th scope="row">2024年1月</th>
            <td>120</td>
            <td>+15%</td>
            <td>-5%</td>
        </tr>
        <tr>
            <th scope="row">2024年2月</th>
            <td>135</td>
            <td>+18%</td>
            <td>+12.5%</td>
        </tr>
        <tr>
            <th scope="row">2024年3月</th>
            <td>158</td>
            <td>+22%</td>
            <td>+17%</td>
        </tr>
    </tbody>
</table>

复杂表格的标记

html
<table>
    <caption>学生成绩统计表</caption>
    <thead>
        <tr>
            <th id="name">姓名</th>
            <th id="math" scope="col">数学</th>
            <th id="english" scope="col">英语</th>
            <th id="science" scope="col">科学</th>
            <th id="total" scope="col">总分</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th id="student1" scope="row">张小明</th>
            <td headers="student1 math">85</td>
            <td headers="student1 english">92</td>
            <td headers="student1 science">88</td>
            <td headers="student1 total">265</td>
        </tr>
        <tr>
            <th id="student2" scope="row">李小红</th>
            <td headers="student2 math">90</td>
            <td headers="student2 english">87</td>
            <td headers="student2 science">93</td>
            <td headers="student2 total">270</td>
        </tr>
    </tbody>
</table>

数据表格应用

财务报表

html
<style>
.financial-table {
    width: 100%;
    border-collapse: collapse;
    margin: 20px 0;
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

.financial-table caption {
    font-size: 1.5em;
    font-weight: bold;
    margin-bottom: 15px;
    color: #333;
}

.financial-table th {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    padding: 15px;
    text-align: center;
    border: 1px solid #5a67d8;
}

.financial-table td {
    padding: 12px;
    border: 1px solid #e2e8f0;
    text-align: right;
}

.financial-table tbody tr:nth-child(even) {
    background-color: #f7fafc;
}

.financial-table .category {
    background-color: #edf2f7;
    font-weight: bold;
    text-align: left;
}

.financial-table .positive {
    color: #38a169;
}

.financial-table .negative {
    color: #e53e3e;
}

.financial-table .total {
    background-color: #e6fffa;
    font-weight: bold;
    border-top: 2px solid #38b2ac;
}
</style>

<table class="financial-table">
    <caption>2024年第一季度财务报表</caption>
    <thead>
        <tr>
            <th>项目</th>
            <th>1月</th>
            <th>2月</th>
            <th>3月</th>
            <th>季度总计</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td class="category">收入</td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td> 产品销售</td>
            <td class="positive">¥280,000</td>
            <td class="positive">¥320,000</td>
            <td class="positive">¥350,000</td>
            <td class="positive">¥950,000</td>
        </tr>
        <tr>
            <td> 服务收入</td>
            <td class="positive">¥45,000</td>
            <td class="positive">¥52,000</td>
            <td class="positive">¥48,000</td>
            <td class="positive">¥145,000</td>
        </tr>
        <tr class="total">
            <td><strong>收入小计</strong></td>
            <td><strong>¥325,000</strong></td>
            <td><strong>¥372,000</strong></td>
            <td><strong>¥398,000</strong></td>
            <td><strong>¥1,095,000</strong></td>
        </tr>
        <tr>
            <td class="category">支出</td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td> 人员成本</td>
            <td class="negative">¥180,000</td>
            <td class="negative">¥180,000</td>
            <td class="negative">¥185,000</td>
            <td class="negative">¥545,000</td>
        </tr>
        <tr>
            <td> 运营费用</td>
            <td class="negative">¥65,000</td>
            <td class="negative">¥72,000</td>
            <td class="negative">¥68,000</td>
            <td class="negative">¥205,000</td>
        </tr>
        <tr class="total">
            <td><strong>支出小计</strong></td>
            <td><strong>¥245,000</strong></td>
            <td><strong>¥252,000</strong></td>
            <td><strong>¥253,000</strong></td>
            <td><strong>¥750,000</strong></td>
        </tr>
        <tr class="total">
            <td><strong>净利润</strong></td>
            <td class="positive"><strong>¥80,000</strong></td>
            <td class="positive"><strong>¥120,000</strong></td>
            <td class="positive"><strong>¥145,000</strong></td>
            <td class="positive"><strong>¥345,000</strong></td>
        </tr>
    </tbody>
</table>

产品比较表

html
<style>
.comparison-table {
    width: 100%;
    border-collapse: collapse;
    margin: 30px 0;
    background: white;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    border-radius: 10px;
    overflow: hidden;
}

.comparison-table th {
    background: linear-gradient(45deg, #007acc, #0099ff);
    color: white;
    padding: 20px 15px;
    text-align: center;
    font-weight: bold;
}

.comparison-table td {
    padding: 15px;
    text-align: center;
    border-bottom: 1px solid #f0f0f0;
}

.comparison-table .feature {
    text-align: left;
    font-weight: bold;
    background-color: #f8f9fa;
    border-right: 2px solid #e9ecef;
}

.comparison-table .check {
    color: #28a745;
    font-size: 1.2em;
}

.comparison-table .cross {
    color: #dc3545;
    font-size: 1.2em;
}

.comparison-table .price {
    font-size: 1.3em;
    font-weight: bold;
    color: #007acc;
}

.comparison-table .highlight {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
}

.comparison-table .highlight .price {
    color: #ffd700;
}
</style>

<table class="comparison-table">
    <caption style="font-size: 1.5em; font-weight: bold; margin-bottom: 20px; color: #333;">
        产品套餐比较
    </caption>
    <thead>
        <tr>
            <th style="width: 25%;">功能特性</th>
            <th style="width: 25%;">基础版</th>
            <th style="width: 25%;" class="highlight">专业版</th>
            <th style="width: 25%;">企业版</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td class="feature">月费用</td>
            <td class="price">¥99</td>
            <td class="highlight price">¥199</td>
            <td class="price">¥399</td>
        </tr>
        <tr>
            <td class="feature">用户数量</td>
            <td>5个用户</td>
            <td class="highlight">20个用户</td>
            <td>无限制</td>
        </tr>
        <tr>
            <td class="feature">存储空间</td>
            <td>10GB</td>
            <td class="highlight">100GB</td>
            <td>1TB</td>
        </tr>
        <tr>
            <td class="feature">基础功能</td>
            <td class="check">✓</td>
            <td class="highlight check">✓</td>
            <td class="check">✓</td>
        </tr>
        <tr>
            <td class="feature">高级分析</td>
            <td class="cross">✗</td>
            <td class="highlight check">✓</td>
            <td class="check">✓</td>
        </tr>
        <tr>
            <td class="feature">API访问</td>
            <td class="cross">✗</td>
            <td class="highlight check">✓</td>
            <td class="check">✓</td>
        </tr>
        <tr>
            <td class="feature">优先支持</td>
            <td class="cross">✗</td>
            <td class="highlight cross">✗</td>
            <td class="check">✓</td>
        </tr>
        <tr>
            <td class="feature">自定义品牌</td>
            <td class="cross">✗</td>
            <td class="highlight cross">✗</td>
            <td class="check">✓</td>
        </tr>
    </tbody>
</table>

表格的最佳实践

1. 数据排序和筛选

html
<style>
.sortable-table th {
    cursor: pointer;
    position: relative;
    user-select: none;
}

.sortable-table th:hover {
    background-color: #e6f3ff;
}

.sortable-table th.sort-asc:after {
    content: " ↑";
    color: #007acc;
}

.sortable-table th.sort-desc:after {
    content: " ↓";
    color: #007acc;
}

.filter-input {
    width: 100%;
    padding: 8px;
    margin-bottom: 10px;
    border: 1px solid #ddd;
    border-radius: 4px;
}
</style>

<input type="text" class="filter-input" placeholder="搜索员工姓名..." id="nameFilter">

<table class="sortable-table modern-table">
    <thead>
        <tr>
            <th onclick="sortTable(0)">姓名</th>
            <th onclick="sortTable(1)">部门</th>
            <th onclick="sortTable(2)">工资</th>
            <th onclick="sortTable(3)">入职日期</th>
        </tr>
    </thead>
    <tbody id="employeeTable">
        <tr>
            <td>张三</td>
            <td>技术部</td>
            <td data-value="12000">¥12,000</td>
            <td data-value="2023-03-15">2023-03-15</td>
        </tr>
        <tr>
            <td>李四</td>
            <td>销售部</td>
            <td data-value="8000">¥8,000</td>
            <td data-value="2023-01-10">2023-01-10</td>
        </tr>
        <tr>
            <td>王五</td>
            <td>技术部</td>
            <td data-value="15000">¥15,000</td>
            <td data-value="2022-11-20">2022-11-20</td>
        </tr>
    </tbody>
</table>

<script>
// 简单的表格排序功能
let sortDirection = {};

function sortTable(columnIndex) {
    const table = document.getElementById('employeeTable');
    const rows = Array.from(table.rows);
    
    // 切换排序方向
    sortDirection[columnIndex] = !sortDirection[columnIndex];
    
    rows.sort((a, b) => {
        let aVal = a.cells[columnIndex].dataset.value || a.cells[columnIndex].textContent;
        let bVal = b.cells[columnIndex].dataset.value || b.cells[columnIndex].textContent;
        
        // 尝试转换为数字
        if (!isNaN(aVal) && !isNaN(bVal)) {
            aVal = parseFloat(aVal);
            bVal = parseFloat(bVal);
        }
        
        if (sortDirection[columnIndex]) {
            return aVal > bVal ? 1 : -1;
        } else {
            return aVal < bVal ? 1 : -1;
        }
    });
    
    // 重新插入排序后的行
    rows.forEach(row => table.appendChild(row));
    
    // 更新表头样式
    const headers = document.querySelectorAll('.sortable-table th');
    headers.forEach((header, index) => {
        header.classList.remove('sort-asc', 'sort-desc');
        if (index === columnIndex) {
            header.classList.add(sortDirection[columnIndex] ? 'sort-asc' : 'sort-desc');
        }
    });
}

// 简单的筛选功能
document.getElementById('nameFilter').addEventListener('input', function() {
    const filter = this.value.toLowerCase();
    const rows = document.getElementById('employeeTable').rows;
    
    for (let i = 0; i < rows.length; i++) {
        const name = rows[i].cells[0].textContent.toLowerCase();
        rows[i].style.display = name.includes(filter) ? '' : 'none';
    }
});
</script>

常见错误

1. 表格结构不完整

html
<!-- 错误:缺少表头 -->
<table>
    <tr>
        <td>张三</td>
        <td>25</td>
    </tr>
</table>

<!-- 正确:包含表头 -->
<table>
    <tr>
        <th>姓名</th>
        <th>年龄</th>
    </tr>
    <tr>
        <td>张三</td>
        <td>25</td>
    </tr>
</table>

2. 滥用表格做布局

html
<!-- 错误:用表格做页面布局 -->
<table>
    <tr>
        <td>导航菜单</td>
        <td>主要内容</td>
        <td>侧边栏</td>
    </tr>
</table>

<!-- 正确:使用CSS布局 -->
<div class="layout">
    <nav>导航菜单</nav>
    <main>主要内容</main>
    <aside>侧边栏</aside>
</div>

3. 缺乏可访问性

html
<!-- 错误:缺少标题和语义信息 -->
<table>
    <tr><td>数据</td><td>数据</td></tr>
</table>

<!-- 正确:包含完整的语义信息 -->
<table>
    <caption>数据说明</caption>
    <thead>
        <tr>
            <th scope="col">列标题1</th>
            <th scope="col">列标题2</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>数据1</td>
            <td>数据2</td>
        </tr>
    </tbody>
</table>

小结

  • 表格用于显示结构化的行列数据
  • 基本结构包括 <table><tr><th><td>
  • 使用 <thead><tbody><tfoot> 增强语义
  • colspanrowspan 用于合并单元格
  • 现代表格应该注重样式和响应式设计
  • 添加适当的可访问性属性
  • 避免使用表格进行页面布局
  • 考虑用户体验,如排序、筛选功能

下一章我们将学习HTML列表的创建和使用。