跳到主要内容

HTML 表单

表单是网页与用户交互的重要工具,用于收集用户输入的数据。本章将详细介绍 HTML 表单的各种元素和属性。

表单基础

什么是表单?

表单(Form)是一个包含表单元素的区域,用于收集用户输入并提交到服务器。常见的表单应用包括:

  • 用户注册和登录
  • 搜索框
  • 反馈留言
  • 在线问卷
  • 文件上传

表单结构

<form action="/submit" method="POST">
<!-- 表单元素 -->
<input type="text" name="username">
<button type="submit">提交</button>
</form>

form 元素属性

属性说明
action表单提交的目标 URL
methodHTTP 请求方法(GET 或 POST)
target提交后的响应显示位置
enctype编码类型,用于文件上传
autocomplete是否启用自动完成
novalidate禁用浏览器默认验证

method 属性

<!-- GET 方法 - 参数在 URL 中显示,适合搜索 -->
<form action="/search" method="GET">
<input type="text" name="q">
<button>搜索</button>
</form>
<!-- 提交后 URL: /search?q=关键词 -->

<!-- POST 方法 - 参数在请求体中,适合提交数据 -->
<form action="/register" method="POST">
<input type="text" name="username">
<button>注册</button>
</form>

enctype 属性

<!-- 默认值,表单数据编码为 URL 编码 -->
<form enctype="application/x-www-form-urlencoded">
<!-- 适合普通文本输入 -->
</form>

<!-- 文件上传必须使用 multipart/form-data -->
<form enctype="multipart/form-data">
<input type="file" name="avatar">
<button>上传</button>
</form>

输入元素 <input>

<input> 是最常用的表单元素,通过 type 属性可以创建不同类型的输入框。

文本输入

<!-- 普通文本 -->
<input type="text" name="username" placeholder="请输入用户名">

<!-- 密码输入 -->
<input type="password" name="password" placeholder="请输入密码">

<!-- 效果预览: -->
<input type="text" placeholder="请输入用户名" style="padding: 8px; margin: 5px;">
<input type="password" placeholder="请输入密码" style="padding: 8px; margin: 5px;">

邮箱和电话

<!-- 邮箱 - 会验证邮箱格式 -->
<input type="email" name="email" placeholder="[email protected]">

<!-- 电话 - 移动端会弹出数字键盘 -->
<input type="tel" name="phone" placeholder="138-0000-0000">

<!-- URL - 会验证 URL 格式 -->
<input type="url" name="website" placeholder="https://example.com">

<!-- 搜索框 -->
<input type="search" name="search" placeholder="搜索...">

数字输入

<!-- 数字输入 -->
<input type="number" name="age" min="0" max="120" step="1">

<!-- 带范围限制 -->
<input type="number" name="price" min="0" max="1000" step="0.01">

<!-- 效果预览: -->
<input type="number" min="0" max="120" step="1" style="padding: 8px; margin: 5px;">

范围滑块

<input type="range" name="volume" min="0" max="100" value="50">

<!-- 带刻度标记 -->
<input type="range" name="brightness" min="0" max="100" value="50" step="10">

<!-- 效果预览: -->
<input type="range" min="0" max="100" value="50" style="width: 200px;">

日期和时间

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

<!-- 时间 -->
<input type="time" name="alarm">

<!-- 日期和时间 -->
<input type="datetime-local" name="meeting">

<!-- 月份 -->
<input type="month" name="birth-month">

<!-- 周 -->
<input type="week" name="week">

<!-- 效果预览: -->
<input type="date" style="padding: 8px; margin: 5px;">
<input type="time" style="padding: 8px; margin: 5px;">

颜色选择

<input type="color" name="theme" value="#3498db">

<!-- 效果预览: -->
<input type="color" value="#3498db">

复选框和单选框

<!-- 单选框 - 同一 name 只能选一个 -->
<input type="radio" name="gender" value="male">
<input type="radio" name="gender" value="female">
<input type="radio" name="gender" value="other"> 其他

<!-- 复选框 - 可以选择多个 -->
<input type="checkbox" name="hobby" value="reading"> 阅读
<input type="checkbox" name="hobby" value="travel"> 旅行
<input type="checkbox" name="hobby" value="sports"> 运动

<!-- 效果预览: -->
<label style="margin-right: 15px;"><input type="radio" name="gender" value="male"></label>
<label style="margin-right: 15px;"><input type="radio" name="gender" value="female"></label>
<label><input type="radio" name="gender" value="other"> 其他</label>
<br><br>
<label style="margin-right: 15px;"><input type="checkbox" name="hobby" value="reading"> 阅读</label>
<label style="margin-right: 15px;"><input type="checkbox" name="hobby" value="travel"> 旅行</label>
<label><input type="checkbox" name="hobby" value="sports"> 运动</label>

文件上传

<!-- 普通文件上传 -->
<input type="file" name="document">

<!-- 多文件上传 -->
<input type="file" name="photos" multiple>

<!-- 指定接受的文件类型 -->
<input type="file" name="avatar" accept="image/*"> <!-- 图片 -->
<input type="file" name="doc" accept=".pdf,.doc,.docx"> <!-- 指定格式 -->

<!-- 效果预览: -->
<input type="file" style="margin: 10px;">

隐藏字段

<!-- 隐藏字段,不会显示但会提交 -->
<input type="hidden" name="user_id" value="12345">
<input type="hidden" name="token" value="abc123">

其他表单元素

下拉选择 <select>

<select name="country">
<option value="">请选择国家</option>
<option value="cn">中国</option>
<option value="us">美国</option>
<option value="jp">日本</option>
</select>

<!-- 分组选项 -->
<select name="city">
<optgroup label="北京市">
<option value="bj-dc">东城区</option>
<option value="bj-xc">西城区</option>
</optgroup>
<optgroup label="上海市">
<option value="sh-hp">黄浦区</option>
<option value="sh-xh">徐汇区</option>
</optgroup>
</select>

<!-- 效果预览: -->
<select style="padding: 8px; margin: 5px;">
<option value="">请选择国家</option>
<option value="cn">中国</option>
<option value="us">美国</option>
<option value="jp">日本</option>
</select>

多行文本 <textarea>

<textarea name="message" rows="5" cols="40" placeholder="请输入留言内容..."></textarea>

<!-- 自动调整大小 -->
<textarea name="bio"
rows="3"
minlength="10"
maxlength="200"
placeholder="自我介绍..."></textarea>

<!-- 效果预览: -->
<textarea rows="3" cols="40" placeholder="请输入留言内容..." style="padding: 8px;"></textarea>

按钮

<!-- 提交按钮 -->
<button type="submit">提交</button>

<!-- 重置按钮 -->
<button type="reset">重置</button>

<!-- 普通按钮 -->
<button type="button" onclick="alert('Hello!')">点击</button>

<!-- 也可以用 input -->
<input type="submit" value="提交">
<input type="reset" value="重置">
<input type="button" value="按钮">

<!-- 效果预览: -->
<button type="submit" style="padding: 8px 16px; margin: 5px;">提交</button>
<button type="reset" style="padding: 8px 16px; margin: 5px;">重置</button>
<button type="button" style="padding: 8px 16px; margin: 5px;">点击</button>

表单元素属性

通用属性

属性说明
name字段名称,用于提交数据
value字段值
placeholder占位提示文本
disabled禁用该字段
readonly只读,不可修改
required必填字段
autofocus页面加载时自动聚焦
autocomplete自动完成建议
<!-- 完整示例 -->
<input type="text"
name="username"
value="张三"
placeholder="请输入用户名"
required
autofocus
autocomplete="username">

验证属性

<!-- 最小/最大长度 -->
<input type="text" name="username" minlength="3" maxlength="20">

<!-- 最小/最大值 -->
<input type="number" name="age" min="0" max="150">

<!-- 模式匹配(正则) -->
<input type="text" name="phone" pattern="1[3-9]\d{9}" title="请输入正确的手机号">

<!-- 步骤值 -->
<input type="number" name="price" min="0" step="0.01">

表单结构化

label 标签

使用 <label> 为表单元素添加标签,提高可用性和可访问性:

<!-- 方式1:嵌套关联 -->
<label>
用户名:
<input type="text" name="username">
</label>

<!-- 方式2:for 属性关联 -->
<label for="email">邮箱:</label>
<input type="email" id="email" name="email">

<!-- 效果预览: -->
<div style="margin: 10px 0;">
<label for="email-demo">邮箱:</label>
<input type="email" id="email-demo" style="padding: 8px;">
</div>

fieldset 和 legend

使用 <fieldset> 对表单元素进行分组:

<form>
<fieldset>
<legend>个人信息</legend>

<label for="name">姓名:</label>
<input type="text" id="name" name="name">

<label for="email">邮箱:</label>
<input type="email" id="email" name="email">
</fieldset>

<fieldset>
<legend>教育背景</legend>

<label for="school">学校:</label>
<input type="text" id="school" name="school">
</fieldset>

<button type="submit">提交</button>
</form>

<!-- 效果预览: -->
<fieldset style="padding: 15px; margin: 10px 0;">
<legend style="font-weight: bold;">个人信息</legend>
<div style="margin: 10px 0;">
<label for="name-demo">姓名:</label>
<input type="text" id="name-demo" style="padding: 8px;">
</div>
</fieldset>

完整表单示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>用户注册表单</title>
<style>
form {
max-width: 500px;
margin: 20px auto;
padding: 20px;
border: 1px solid #ddd;
border-radius: 8px;
}
.form-group {
margin-bottom: 15px;
}
label {
display: inline-block;
width: 100px;
text-align: right;
margin-right: 10px;
}
input, select, textarea {
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
width: 250px;
}
button {
padding: 10px 30px;
background-color: #3498db;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #2980b9;
}
</style>
</head>
<body>
<form action="/register" method="POST">
<h2>用户注册</h2>

<div class="form-group">
<label for="username">用户名:</label>
<input type="text" id="username" name="username"
required minlength="3" maxlength="20"
placeholder="3-20个字符">
</div>

<div class="form-group">
<label for="email">邮箱:</label>
<input type="email" id="email" name="email" required>
</div>

<div class="form-group">
<label for="password">密码:</label>
<input type="password" id="password" name="password"
required minlength="6">
</div>

<div class="form-group">
<label for="phone">手机号:</label>
<input type="tel" id="phone" name="phone"
pattern="1[3-9]\d{9}"
placeholder="138-0000-0000">
</div>

<div class="form-group">
<label for="gender">性别:</label>
<label><input type="radio" name="gender" value="male"></label>
<label><input type="radio" name="gender" value="female"></label>
</div>

<div class="form-group">
<label for="country">国家:</label>
<select id="country" name="country">
<option value="">请选择</option>
<option value="cn">中国</option>
<option value="us">美国</option>
<option value="jp">日本</option>
</select>
</div>

<div class="form-group">
<label for="avatar">头像:</label>
<input type="file" id="avatar" name="avatar" accept="image/*">
</div>

<div class="form-group">
<label for="bio">个人简介:</label>
<textarea id="bio" name="bio" rows="4"
maxlength="200" placeholder="介绍一下自己..."></textarea>
</div>

<div class="form-group">
<label>
<input type="checkbox" name="agree" required>
我同意用户协议
</label>
</div>

<div class="form-group" style="text-align: center;">
<button type="submit">注册</button>
<button type="reset">重置</button>
</div>
</form>
</body>
</html>

表单验证

浏览器内置验证

HTML5 提供了内置的表单验证功能:

<!-- 必填 -->
<input type="text" required>

<!-- 邮箱格式 -->
<input type="email">

<!-- URL格式 -->
<input type="url">

<!-- 数字范围 -->
<input type="number" min="0" max="100">

<!-- 自定义正则 -->
<input type="text" pattern="[A-Za-z]{3}">

<!-- 自定义提示 -->
<input type="text" required title="此字段必填">

CSS 验证样式

/* 输入有效时 */
input:valid {
border-color: green;
}

/* 输入无效时 */
input:invalid {
border-color: red;
}

/* 必填但为空时 */
input:required:invalid {
background-color: #fff0f0;
}

/* 获得焦点时的无效输入 */
input:focus:invalid {
outline: none;
box-shadow: 0 0 3px red;
}

无障碍考虑

  1. 使用 label:确保所有输入都有关联的 label
  2. 分组相关字段:使用 fieldset 和 legend
  3. 清晰的错误提示:使用 aria-describedby 提供错误信息
  4. 适当的 tab 顺序:确保可以通过键盘导航
<label for="email">邮箱地址</label>
<input type="email" id="email"
aria-describedby="email-help email-error">
<p id="email-help">请输入有效的邮箱地址</p>
<p id="email-error" style="color: red;">格式不正确</p>

小结

本章学习了:

  1. 表单基础form 元素和基本属性
  2. input 类型:text、password、email、number、date、file 等
  3. 其他元素:select、textarea、button
  4. 表单属性:name、value、required、placeholder
  5. 表单验证:内置验证和 CSS 样式
  6. 结构化:label、fieldset、legend
  7. 无障碍:提高表单的可访问性

练习

  1. 创建一个用户登录表单(用户名和密码)
  2. 创建一个包含个人信息、教育背景、工作经历的注册表单
  3. 为表单添加样式,实现基本的布局美化
  4. 添加表单验证(必填、格式验证)
  5. 创建一个文件上传表单,支持多文件上传