全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-17 6 分钟 ✍️ juanwangdev

CSS伪类:valid和:invalid

:valid和:invalid是CSS伪类选择器,根据表单元素的验证状态自动匹配,实现实时的表单验证视觉反馈。

基本语法

CSS
input:valid {
  /* 验证通过时的样式 */
}

input:invalid {
  /* 验证失败时的样式 */
}

工作原理

  1. 浏览器根据表单元素的验证属性自动判断状态
  2. 验证通过时匹配:valid伪类
  3. 验证失败时匹配:invalid伪类
  4. 样式实时更新,无需JavaScript

代码示例

基础样式反馈

HTML
<style>
  input:valid {
    border: 2px solid #27ae60;
    background-color: #e8f5e9;
  }

  input:invalid {
    border: 2px solid #e74c3c;
    background-color: #ffebee;
  }
</style>

<form>
  <label>邮箱:</label>
  <input type="email" required placeholder="example@mail.com">
  <br><br>

  <label>年龄(18-100):</label>
  <input type="number" min="18" max="100" required>
</form>

避免初始错误样式

HTML
<style>
  /* 初始状态不显示错误样式 */
  input:invalid:not(:placeholder-shown) {
    border-color: #e74c3c;
  }

  /* 或者使用:not(:focus) */
  input:invalid:not(:focus) {
    border-color: #e74c3c;
  }

  input:valid {
    border-color: #27ae60;
  }
</style>

<form>
  <input type="email" required placeholder="请输入邮箱">
</form>

配合其他伪类

HTML
<style>
  /* 必填字段标记 */
  input:required {
    border-left: 4px solid #3498db;
  }

  /* 可选字段样式 */
  input:optional {
    border-left: 4px solid #bdc3c7;
  }

  /* 验证通过且已填写 */
  input:valid:not(:placeholder-shown) {
    border-color: #27ae60;
    background-image: url('check.svg');
    background-repeat: no-repeat;
    background-position: right 10px center;
  }

  /* 验证失败且已填写 */
  input:invalid:not(:placeholder-shown) {
    border-color: #e74c3c;
    background-image: url('error.svg');
    background-repeat: no-repeat;
    background-position: right 10px center;
  }
</style>

<form>
  <input type="email" required placeholder="邮箱(必填)">
  <input type="text" placeholder="备注(选填)">
</form>

显示验证图标

HTML
<style>
  .form-group {
    position: relative;
  }

  .form-group input {
    padding-right: 35px;
  }

  .form-group::after {
    position: absolute;
    right: 10px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 18px;
  }

  .form-group:has(input:valid)::after {
    content: '✓';
    color: #27ae60;
  }

  .form-group:has(input:invalid:not(:placeholder-shown))::after {
    content: '✗';
    color: #e74c3c;
  }
</style>

<form>
  <div class="form-group">
    <input type="email" required placeholder="请输入邮箱">
  </div>
  <div class="form-group">
    <input type="url" required placeholder="请输入网址">
  </div>
</form>

错误提示信息

HTML
<style>
  .input-wrapper {
    position: relative;
    margin-bottom: 20px;
  }

  input:valid + .error-msg {
    display: none;
  }

  input:invalid:not(:placeholder-shown) + .error-msg {
    display: block;
    color: #e74c3c;
    font-size: 12px;
    margin-top: 5px;
  }
</style>

<form>
  <div class="input-wrapper">
    <input type="email" required placeholder="邮箱">
    <span class="error-msg">请输入有效的邮箱地址</span>
  </div>

  <div class="input-wrapper">
    <input type="password" minlength="8" required placeholder="密码">
    <span class="error-msg">密码至少8个字符</span>
  </div>
</form>

进阶:动态表单样式

HTML
<style>
  form:valid button[type="submit"] {
    background-color: #27ae60;
    cursor: pointer;
  }

  form:invalid button[type="submit"] {
    background-color: #bdc3c7;
    cursor: not-allowed;
    opacity: 0.7;
  }
</style>

<form>
  <input type="text" required placeholder="用户名">
  <input type="email" required placeholder="邮箱">
  <button type="submit">提交</button>
</form>

验证状态指示器

HTML
<style>
  .validation-indicator {
    display: inline-block;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    margin-left: 8px;
    vertical-align: middle;
  }

  input:valid ~ .validation-indicator {
    background-color: #27ae60;
  }

  input:invalid:not(:placeholder-shown) ~ .validation-indicator {
    background-color: #e74c3c;
  }
</style>

<form>
  <label>
    邮箱:
    <input type="email" required>
    <span class="validation-indicator"></span>
  </label>
</form>

相关伪类

伪类说明
:valid验证通过
:invalid验证失败
:required必填字段
:optional可选字段
:in-range数值在min/max范围内
:out-of-range数值超出min/max范围
:placeholder-shown显示占位符(未填写)
HTML
<style>
  input:in-range {
    border-color: #27ae60;
  }

  input:out-of-range {
    border-color: #e74c3c;
  }
</style>

<input type="number" min="1" max="10" value="5">

注意::valid和:invalid在页面加载时就会应用,建议配合:placeholder-shown或:not(:focus)避免初始状态就显示错误样式。

要点总结

  1. :valid匹配验证通过的元素,:invalid匹配验证失败的元素
  2. 样式实时更新,无需JavaScript
  3. 建议配合:placeholder-shown避免初始错误样式
  4. 可配合:required/:optional/:in-range等伪类使用
  5. :has()伪类可实现更复杂的状态联动样式

📝 发现内容有误?点击此处直接编辑

← 上一篇 语义化优势
下一篇 → HTML checkValidity和reportValidity
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库