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 正则验证

参考链接 ​