Appearance
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>增强语义 colspan和rowspan用于合并单元格- 现代表格应该注重样式和响应式设计
- 添加适当的可访问性属性
- 避免使用表格进行页面布局
- 考虑用户体验,如排序、筛选功能
下一章我们将学习HTML列表的创建和使用。