Skip to content

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+.*">

最佳实践

  1. 标记必填字段:用红色星号 * 或文字标注必填字段
  2. 配合 :valid/:invalid:提供即时视觉反馈
  3. 合理设置 minlength:对文本输入添加最小长度要求
  4. select 第一个 option 为空:使 required 对下拉框生效
  5. checkbox 用于同意条款:协议勾选使用 required
  6. 不要过度使用:只在真正必填的字段上使用

下一节

继续学习:pattern 正则验证

参考链接