Validación con CSS :invalid + :has()

Explicación

:invalid se activa cuando un campo del formulario no cumple las reglas de validación (por ejemplo, un email sin @ o un texto demasiado corto).

:has() permite seleccionar un elemento en función de lo que contiene. Aquí lo usamos en el formulario:

CSS

form:has(:invalid) { … }

Eso significa: “Si dentro del formulario hay algún campo inválido, aplica estos estilos al formulario completo”.

  • El borde y sombra del <input> cambian cuando está inválido.
  • El <form> completo se resalta en rojo si contiene al menos un campo inválido.
     
     
HTML

<form>
  <label>
    Email:
    <input 
      type="email" 
      placeholder="tu@email.com" 
      required>
  </label>
  <label>
    Nombre:
    <input 
      type="text" 
      required 
      minlength="3">
  </label>
  <button type="submit">Enviar</button>
</form>

CSS


form {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 1.5rem;
  background: white;
  border-radius: 0.5rem;
  box-shadow: 0 2px 6px rgba(0,0,0,0.1);
  transition: border 0.3s ease, box-shadow 0.3s ease;
}

input {
  padding: 0.8rem;
  font-size: 1rem;
  border: 2px solid #ccc;
  border-radius: 0.4rem;
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
}

/* Cuando el input es inválido */
input:invalid {
  border-color: #e74c3c;
  box-shadow: 0 0 5px rgba(231, 76, 60, 0.5);
}

/* Si el formulario contiene un input inválido */
form:has(:invalid) {
  border: 2px solid #e74c3c;
  box-shadow: 0 0 10px rgba(231, 76, 60, 0.4);
}

button {
  padding: 0.8rem 1.5rem;
  border: none;
  border-radius: 0.4rem;
  background: #3498db;
  color: white;
  font-size: 1rem;
  cursor: pointer;
  transition: background 0.3s ease;
}

button:hover {
  background: #2980b9;
}