Skip to content

02|HTML 表单、表格与语义化

页面不只是展示内容,还需要收集用户输入和呈现结构化数据。表单负责收集输入,表格负责展示行列数据,语义化标签则让页面结构对浏览器、搜索引擎和辅助技术更友好。

一、表单基础

表单用 <form> 包裹一组输入控件,用户填写后提交给服务器处理:

html
<form action="/api/login" method="post">
  <label for="username">用户名</label>
  <input type="text" id="username" name="username" placeholder="请输入用户名">

  <label for="password">密码</label>
  <input type="password" id="password" name="password">

  <button type="submit">登录</button>
</form>
属性作用
action数据提交到的 URL
methodHTTP 方法,常用 getpost
name字段名,提交时作为键名
id唯一标识,与 labelfor 关联
placeholder输入框为空时显示的提示文字

labelfor 必须等于对应 inputid。这样点击标签文字时,焦点会自动跳到输入框,对触摸屏和屏幕阅读器都更友好。

常见 input 类型

html
<!-- 文本 -->
<input type="text" name="title">

<!-- 密码(输入内容显示为圆点) -->
<input type="password" name="pwd">

<!-- 邮箱(移动端会弹出邮箱键盘) -->
<input type="email" name="email">

<!-- 数字(带增减按钮) -->
<input type="number" name="count" min="0" max="100">

<!-- 日期选择器 -->
<input type="date" name="birthday">

<!-- 单选 -->
<input type="radio" name="role" value="admin" id="r1">
<label for="r1">管理员</label>
<input type="radio" name="role" value="user" id="r2">
<label for="r2">普通用户</label>

<!-- 多选 -->
<input type="checkbox" name="tags" value="python" id="t1">
<label for="t1">Python</label>
<input type="checkbox" name="tags" value="go" id="t2">
<label for="t2">Go</label>

同一组单选按钮的 name 必须相同,这样浏览器才会把它们当成互斥选项。多选框的 name 也可以相同,提交时该字段会包含多个值。

下拉选择

html
<label for="env">环境</label>
<select id="env" name="env">
  <option value="dev">开发环境</option>
  <option value="test">测试环境</option>
  <option value="prod" selected>生产环境</option>
</select>

selected 表示默认选中项。如果没有 selected,默认选中第一项。

多行文本

html
<label for="desc">描述</label>
<textarea id="desc" name="desc" rows="4" cols="50"></textarea>

textarea 适合长文本输入。rowscols 定义初始尺寸,实际大小通常用 CSS 控制。

表单提交行为

html
<form action="/api/articles" method="post">
  <input type="text" name="title" required>
  <input type="text" name="author">
  <button type="submit">提交</button>
</form>

点击提交按钮后,浏览器会构造 HTTP 请求:

method数据位置URL 示例
getURL 查询参数/api/articles?title=xxx&author=yyy
post请求体URL 是 /api/articles,数据在 body 中

required 属性会在提交前进行基础校验:如果该字段为空,浏览器会阻止提交并提示用户。但这只是前端校验,后端必须再次校验所有输入

在现代单页应用(Vue/React)中,表单通常不通过原生 form 提交,而是用 JavaScript 拦截提交事件、收集数据、通过 fetch 发送。此时 actionmethod 可以省略,name 用于标识字段,button type="submit" 触发提交事件。

二、表格

表格用行(tr)和单元格(td / th)组织数据:

html
<table>
  <thead>
    <tr>
      <th>主机名</th>
      <th>IP 地址</th>
      <th>状态</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>web-01</td>
      <td>192.168.1.10</td>
      <td>运行中</td>
    </tr>
    <tr>
      <td>web-02</td>
      <td>192.168.1.11</td>
      <td>已停止</td>
    </tr>
  </tbody>
</table>
标签作用
table表格容器
thead表头区域
tbody数据主体区域
tr一行
th表头单元格(默认加粗居中)
td普通数据单元格

theadtbody 不是强制标签,但显式分组有助于 CSS 选择器定位,也让屏幕阅读器能正确朗读表头与数据的对应关系。

跨行与跨列

html
<table>
  <tr>
    <th rowspan="2">服务</th>
    <th colspan="2">资源占用</th>
  </tr>
  <tr>
    <th>CPU</th>
    <th>内存</th>
  </tr>
  <tr>
    <td>Nginx</td>
    <td>2%</td>
    <td>128MB</td>
  </tr>
</table>
属性作用
colspan="n"单元格横向占据 n 列
rowspan="n"单元格纵向占据 n 行

使用跨行跨列时,对应位置的 tdth 需要省略,否则表格结构会错乱。

三、语义化标签

HTML5 引入了一组具有明确语义的结构性标签,替代滥用 div 的做法:

html
<!doctype html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8">
  <title>运维管理平台</title>
</head>
<body>
  <header>
    <h1>运维管理平台</h1>
    <nav>
      <a href="/">首页</a>
      <a href="/assets">资产</a>
      <a href="/tasks">任务</a>
    </nav>
  </header>

  <main>
    <article>
      <h2>今日告警</h2>
      <p>共 3 条未处理告警...</p>
    </article>

    <aside>
      <h3>快捷操作</h3>
      <ul>
        <li><a href="/tasks/new">新建任务</a></li>
      </ul>
    </aside>
  </main>

  <footer>
    <p>© 2026 运维团队</p>
  </footer>
</body>
</html>
标签语义类比
header页面或区块的头部原来的 div class="header"
nav导航链接区域原来的 div class="nav"
main页面主要内容(每页应只有一个)原来的 div class="main"
article独立的内容块,可以单独分发文章、帖子、评论
section主题性内容分组章节、区块
aside与主要内容相关的侧边信息侧边栏、提示框
footer页面或区块的底部原来的 div class="footer"

语义化标签本身不改变外观——所有标签在浏览器默认样式下都是块级元素,前后换行。它们的价值在于:

  • 搜索引擎更容易理解页面结构,有助于 SEO
  • 屏幕阅读器可以为用户提供页面导航(如"跳到主要内容")
  • 代码可读性提高,维护时一眼看出各区域用途

四、meta 元信息

head 中的 meta 标签携带浏览器和搜索引擎需要的元信息:

html
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="description" content="运维管理平台 - 资产管理、任务调度、事件记录">
  <title>运维管理平台</title>
  <link rel="stylesheet" href="/style.css">
</head>
meta 标签作用
charset="utf-8"字符编码,防止中文乱码
viewport控制移动端缩放行为,响应式页面必须
description搜索引擎结果页显示的摘要

viewport 的含义:

html
<meta name="viewport" content="width=device-width, initial-scale=1.0">
含义
width=device-width视口宽度等于设备屏幕宽度
initial-scale=1.0初始缩放比例为 1,不放大也不缩小

缺少 viewport 时,移动端浏览器会按桌面宽度渲染页面,导致文字过小、需要手动缩放。

五、常见错误

用 div 代替语义化标签

html
<!-- 不建议 -->
<div class="header">...</div>
<div class="nav">...</div>
<div class="main">...</div>

<!-- 建议 -->
<header>...</header>
<nav>...</nav>
<main>...</main>

语义化标签不会增加代码复杂度,反而提高了可维护性。只有在确实找不到合适语义标签时,才回退到 div

表单缺少 label

html
<!-- 错误:没有 label,点击文字无法聚焦输入框 -->
用户名 <input type="text" name="username">

<!-- 正确 -->
<label for="username">用户名</label>
<input type="text" id="username" name="username">

table 用于布局

html
<!-- 错误:用 table 做页面整体布局 -->
<table>
  <tr><td>左侧栏</td><td>主内容</td></tr>
</table>

表格只应用于展示表格数据。页面布局应使用 CSS(Flexbox、Grid)或语义化标签配合 CSS 实现。