HTML 表单
表单是网页与用户交互的重要工具,用于收集用户输入的数据。本章将详细介绍 HTML 表单的各种元素和属性。
表单基础
什么是表单?
表单(Form)是一个包含表单元素的区域,用于收集用户输入并提交到服务器。常见的表单应用包括:
- 用户注册和登录
- 搜索框
- 反馈留言
- 在线问卷
- 文件上传
表单结构
<form action="/submit" method="POST">
<!-- 表单元素 -->
<input type="text" name="username">
<button type="submit">提交</button>
</form>
form 元素属性
| 属性 | 说明 |
|---|---|
action | 表单提交的目标 URL |
method | HTTP 请求方法(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;
}
无障碍考虑
- 使用 label:确保所有输入都有关联的 label
- 分组相关字段:使用 fieldset 和 legend
- 清晰的错误提示:使用 aria-describedby 提供错误信息
- 适当的 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>
小结
本章学习了:
- 表单基础:
form元素和基本属性 - input 类型:text、password、email、number、date、file 等
- 其他元素:select、textarea、button
- 表单属性:name、value、required、placeholder
- 表单验证:内置验证和 CSS 样式
- 结构化:label、fieldset、legend
- 无障碍:提高表单的可访问性
练习
- 创建一个用户登录表单(用户名和密码)
- 创建一个包含个人信息、教育背景、工作经历的注册表单
- 为表单添加样式,实现基本的布局美化
- 添加表单验证(必填、格式验证)
- 创建一个文件上传表单,支持多文件上传