required 必填验证
required 属性标记表单控件为必填项。当表单提交时,如果带有 required 的控件值为空,浏览器会阻止提交并显示内置验证提示。这是 HTML5 表单验证最基础也最常用的功能,无需 JavaScript 即可实现简单的必填校验。
前置知识
阅读本节前,建议先了解:placeholder 占位提示
基础概念
什么是 required 验证
required 是一个布尔属性,添加后表示该字段必须有值才能提交表单。浏览器在提交时自动检查所有 required 控件,如果发现空值则阻止提交。
- 内置验证:无需 JavaScript,浏览器原生支持
- 阻止提交:验证失败时表单不会提交
- 默认提示:浏览器显示默认验证消息
- 伪类反馈:通过
:valid和:invalid伪类提供视觉反馈
支持的控件类型
| 控件类型 | required 支持 | 说明 |
|---|---|---|
text, search, url, tel, email, password | ✅ | 文本不能为空 |
number, range, date, time 等 | ✅ | 必须有值 |
checkbox | ✅ | 必须勾选 |
radio | ✅ | 至少选中一个(同 name 组) |
file | ✅ | 必须选择文件 |
select (含 option) | ✅ | 必须选择(需第一个 option 为空) |
hidden | ❌ | 不适用 |
button | ❌ | 不适用 |
fieldset | ❌ | 不适用(但 disabled 可以阻止) |
语法
基本用法
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>required 基本示例</title>
</head>
<body>
<h2>注册表单</h2>
<form>
<div>
<label for="username">用户名 <span style="color: red;">*</span>:</label>
<input type="text" id="username" name="username" required>
</div>
<div>
<label for="email">邮箱 <span style="color: red;">*</span>:</label>
<input type="email" id="email" name="email" required>
</div>
<div>
<label for="password">密码 <span style="color: red;">*</span>:</label>
<input type="password" id="password" name="password" required>
</div>
<button type="submit">注册</button>
</form>
</body>
</html>各种控件的 required
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>required 多种控件</title>
</head>
<body>
<h2>各控件类型的 required</h2>
<form>
<!-- 文本必填 -->
<div>
<label for="name">姓名:</label>
<input type="text" id="name" name="name" required>
</div>
<!-- 邮箱必填 -->
<div>
<label for="email">邮箱:</label>
<input type="email" id="email" name="email" required>
</div>
<!-- 复选框必填(必须勾选) -->
<div>
<label>
<input type="checkbox" name="agree" required>
我同意服务条款
</label>
</div>
<!-- 单选按钮必填(至少选一个) -->
<div>
<span>性别:</span>
<label><input type="radio" name="gender" value="male" required> 男</label>
<label><input type="radio" name="gender" value="female"> 女</label>
</div>
<!-- 文件必填 -->
<div>
<label for="avatar">头像:</label>
<input type="file" id="avatar" name="avatar" required>
</div>
<!-- 下拉框必填(第一个 option 值为空) -->
<div>
<label for="city">城市:</label>
<select id="city" name="city" required>
<option value="">请选择城市</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
</select>
</div>
<button type="submit">提交</button>
</form>
</body>
</html>详细说明
:valid 和 :invalid 伪类
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>:valid :invalid 伪类</title>
<style>
body { font-family: sans-serif; max-width: 600px; margin: 40px auto; }
label { display: block; margin-bottom: 4px; font-weight: 600; }
input {
width: 100%;
padding: 8px 12px;
border: 2px solid #ddd;
border-radius: 6px;
box-sizing: border-box;
margin-bottom: 12px;
}
/* 验证通过的样式 */
input:valid {
border-color: #27ae60;
}
/* 验证失败的样式 */
input:invalid:not(:placeholder-shown) {
border-color: #e74c3c;
}
/* 聚焦时的样式优先级高于 :valid/:invalid */
input:focus {
box-shadow: 0 0 0 3px rgba(74, 144, 217, 0.2);
outline: none;
}
</style>
</head>
<body>
<h2>验证状态样式</h2>
<form>
<label for="username">用户名(必填):</label>
<input type="text" id="username" name="username" required>
<label for="email">邮箱(必填):</label>
<input type="email" id="email" name="email" required>
<label for="website">网站(选填):</label>
<input type="url" id="website" name="website">
<button type="submit">提交</button>
</form>
<p>输入框边框颜色会根据验证状态变化:</p>
<ul>
<li>红色边框 = 必填但未填写,或格式不正确</li>
<li>绿色边框 = 已填写且格式正确</li>
</ul>
</body>
</html>自定义验证提示消息
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>自定义验证消息</title>
<style>
body { font-family: sans-serif; max-width: 600px; margin: 40px auto; }
.form-group { margin-bottom: 16px; }
label { display: block; margin-bottom: 4px; font-weight: 600; }
input { width: 100%; padding: 8px 12px; border: 2px solid #ddd; border-radius: 6px; box-sizing: border-box; }
.error-msg {
color: #e74c3c;
font-size: 14px;
margin-top: 4px;
display: none;
}
input:invalid:not(:focus):not(:placeholder-shown) ~ .error-msg { display: block; }
</style>
</head>
<body>
<h2>自定义验证提示</h2>
<form>
<div class="form-group">
<label for="username">用户名:</label>
<input type="text" id="username" name="username" required
minlength="3" maxlength="20" placeholder="3-20 个字符">
<p class="error-msg">用户名需要 3-20 个字符</p>
</div>
<div class="form-group">
<label for="email">邮箱:</label>
<input type="email" id="email" name="email" required placeholder="your@email.com">
<p class="error-msg">请输入有效的邮箱地址</p>
</div>
<div class="form-group">
<label>
<input type="checkbox" name="agree" required>
我已阅读并同意服务条款
</label>
<p class="error-msg">必须同意条款才能注册</p>
</div>
<button type="submit">注册</button>
</form>
</body>
</html>JavaScript 检查 required 状态
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>JS 检查 required</title>
</head>
<body>
<h2>JavaScript 验证</h2>
<form id="check-form">
<label for="username">用户名:</label>
<input type="text" id="username" name="username" required>
<br>
<label for="email">邮箱:</label>
<input type="email" id="email" name="email" required>
<br>
<button type="submit">提交</button>
</form>
<p id="result"></p>
<script>
const form = document.getElementById('check-form');
const result = document.getElementById('result');
form.addEventListener('submit', function (e) {
e.preventDefault();
// 使用 checkValidity() 检查整个表单
const isValid = form.checkValidity();
if (isValid) {
result.textContent = '所有必填字段已填写';
result.style.color = 'green';
} else {
result.textContent = '请填写所有必填字段';
result.style.color = 'red';
// 使用 reportValidity() 显示浏览器默认提示
// form.reportValidity();
}
// 检查单个字段
const username = document.getElementById('username');
console.log('用户名必填:', username.required);
console.log('用户名是否为空:', username.value === '');
console.log('用户名是否有效:', username.validity.valid);
});
</script>
</body>
</html>实战示例
完整注册表单验证
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>注册验证</title>
<style>
body { font-family: sans-serif; max-width: 600px; margin: 40px auto; }
.form-group { margin-bottom: 16px; }
label { display: block; margin-bottom: 4px; font-weight: 600; }
.required-star { color: red; }
input, select {
width: 100%;
padding: 8px 12px;
border: 2px solid #ddd;
border-radius: 6px;
box-sizing: border-box;
font-size: 16px;
}
input:valid, select:valid { border-color: #27ae60; }
input:invalid:not(:focus):not(:placeholder-shown),
select:invalid:not(:focus) { border-color: #e74c3c; }
input:focus, select:focus { outline: none; box-shadow: 0 0 0 3px rgba(74,144,217,0.2); }
button {
padding: 12px 32px;
background: #4a90d9;
color: #fff;
border: none;
border-radius: 6px;
font-size: 16px;
cursor: pointer;
}
button:hover { background: #357abd; }
.success-msg {
padding: 12px;
background: #d4edda;
color: #155724;
border-radius: 6px;
margin-top: 16px;
display: none;
}
</style>
</head>
<body>
<h2>用户注册</h2>
<form id="register-form">
<div class="form-group">
<label for="username">用户名 <span class="required-star">*</span></label>
<input type="text" id="username" name="username" required
minlength="3" placeholder="至少 3 个字符">
</div>
<div class="form-group">
<label for="email">邮箱 <span class="required-star">*</span></label>
<input type="email" id="email" name="email" required placeholder="your@email.com">
</div>
<div class="form-group">
<label for="password">密码 <span class="required-star">*</span></label>
<input type="password" id="password" name="password" required minlength="6"
placeholder="至少 6 位">
</div>
<div class="form-group">
<label for="city">城市 <span class="required-star">*</span></label>
<select id="city" name="city" required>
<option value="">请选择</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="guangzhou">广州</option>
</select>
</div>
<div class="form-group">
<label>
<input type="checkbox" name="agree" required> 我同意服务条款
</label>
</div>
<button type="submit">注册</button>
</form>
<div class="success-msg" id="success">注册成功!</div>
<script>
document.getElementById('register-form').addEventListener('submit', function (e) {
e.preventDefault();
if (this.checkValidity()) {
document.getElementById('success').style.display = 'block';
} else {
this.reportValidity();
}
});
</script>
</body>
</html>注意事项
placeholder 不算有值
有 placeholder 但用户没有输入的控件,required 验证仍然会失败。
disabled 控件不验证
被 disabled 的控件不参与表单验证,即使设置了 required。
hidden 控件不验证
type="hidden" 的控件虽然可以有 required,但通常不需要。
空格也算值
如果用户只输入了空格,required 验证会通过(因为值不为空字符串)。如果需要排除纯空格,应使用 pattern 验证:
html
<!-- 允许纯空格通过 -->
<input type="text" required>
<!-- 不允许纯空格 -->
<input type="text" required pattern="\S+.*">最佳实践
- 标记必填字段:用红色星号
*或文字标注必填字段 - 配合 :valid/:invalid:提供即时视觉反馈
- 合理设置 minlength:对文本输入添加最小长度要求
- select 第一个 option 为空:使
required对下拉框生效 - checkbox 用于同意条款:协议勾选使用
required - 不要过度使用:只在真正必填的字段上使用
下一节
继续学习:pattern 正则验证