Back

Atributos Nativos de Validación HTML que los Desarrolladores Suelen Pasar por Alto

Atributos Nativos de Validación HTML que los Desarrolladores Suelen Pasar por Alto

Estás escribiendo JavaScript personalizado para validar formularios que HTML podría manejar de forma nativa. La mayoría de los desarrolladores frontend conocen required y pattern, pero la plataforma ofrece mucho más: atributos que reducen código, mejoran la accesibilidad y crean mejor UX sin dependencias de frameworks.

Este artículo cubre los atributos de validación HTML que probablemente estás pasando por alto, además de las características de CSS y JavaScript que hacen que la validación nativa de formularios sea genuinamente útil.

Puntos Clave

  • El atributo form permite que los controles se asocien con formularios por ID, independientemente de su posición en el DOM, eliminando estructuras complejas de contenedores.
  • Los atributos por botón como formaction, formmethod y formnovalidate permiten que un único formulario se comporte de manera diferente según qué botón lo envíe.
  • Los tokens modernos de autocomplete (new-password, one-time-code, webauthn) mejoran la precisión del autocompletado y activan características del navegador como generadores de contraseñas.
  • El pseudo-selector CSS :user-invalid resuelve el problema de “bordes rojos al cargar la página” mostrando errores solo después de la interacción del usuario.
  • La API de Validación de Restricciones (setCustomValidity(), checkValidity(), reportValidity()) proporciona control programático cuando la validación nativa necesita ser ampliada.

El Atributo form: Controles Fuera de Formularios

¿Necesitas un botón de envío en el encabezado de tu página mientras el formulario está en el contenido principal? El atributo form permite que cualquier control se asocie con un formulario por ID, independientemente de su posición en el DOM.

<form id="checkout">
  <input type="email" name="email" required>
</form>

<button type="submit" form="checkout">Completar Compra</button>

Esto elimina las acrobacias con contenedores y funciona con inputs, botones, selects y textareas por igual.

Sobrescrituras por Botón que Deberías Conocer

Un único formulario puede comportarse de manera diferente dependiendo de qué botón lo envíe. Estos atributos sobrescriben la configuración del formulario padre:

  • formaction — Enviar a una URL diferente
  • formmethod — Usar GET en lugar de POST (o viceversa)
  • formenctype — Cambiar la codificación para cargas de archivos
  • formtarget — Abrir la respuesta en una nueva pestaña
  • formnovalidate — Omitir la validación por completo

El atributo formnovalidate merece especial atención. Es esencial para botones de “Guardar Borrador” donde los datos incompletos son aceptables.

Validación con Pattern y Mensajes de Error Útiles

El atributo pattern acepta expresiones regulares, pero los navegadores muestran errores genéricos por defecto. Combínalo con title para proporcionar contexto:

<input type="text" 
       pattern="[A-Z]{2}[0-9]{6}" 
       title="Formato: Dos letras seguidas de seis dígitos (ej., AB123456)">

Nota: cuando multiple está establecido en inputs como type="email", el patrón se aplica a cada valor individual, no a la cadena completa separada por comas.

Tokens Modernos de autocomplete

Más allá de on y off, autocomplete acepta tokens semánticos que mejoran la precisión del autocompletado:

  • autocomplete="new-password" — Activa generadores de contraseñas
  • autocomplete="one-time-code" — Optimiza para verificación por SMS
  • autocomplete="webauthn" — Señala campos de credenciales passkey

Estos tokens reducen la fricción y señalan la intención a los navegadores y gestores de contraseñas (consulta la lista completa de tokens en la especificación HTML y la documentación de autocomplete en MDN).

El Atributo dirname para Internacionalización

Al soportar idiomas de derecha a izquierda, dirname envía automáticamente la dirección del texto junto con el valor:

<input type="text" name="comment" dirname="comment.dir">

El formulario envía tanto comment (el valor) como comment.dir (ltr o rtl). Esencial para la correcta visualización de contenido generado por usuarios.

El Matiz de readonly

Un error común: los campos readonly participan en el envío del formulario pero se comportan de manera diferente con la validación. Envían valores y pueden recibir el foco.

Sin embargo, los controles readonly están excluidos de la validación de restricciones en HTML moderno. Esto significa que atributos como required, pattern, min o max son ignorados para propósitos de validación en inputs readonly en todos los navegadores modernos actuales.

Si necesitas mostrar un valor sin permitir ediciones y sin enviarlo, disabled suele ser la mejor opción, aunque los campos deshabilitados no envían sus valores.

CSS :user-invalid para UX Moderna en Formularios

El pseudo-selector clásico :invalid se activa inmediatamente, mostrando errores antes de que los usuarios interactúen. El más reciente :user-invalid solo coincide después de la interacción del usuario, resolviendo el problema de “bordes rojos al cargar la página”.

input:user-invalid {
  border-color: #dc3545;
}

input:user-valid {
  border-color: #28a745;
}

Esto crea mejor UX sin lógica de temporización en JavaScript. El soporte en navegadores es ahora sólido en todos los navegadores modernos (consulta :user-invalid en MDN).

La API de Validación de Restricciones

Cuando la validación nativa necesita ser ampliada, la API de Validación de Restricciones proporciona control programático:

  • checkValidity() — Devuelve un booleano, dispara el evento invalid en caso de fallo
  • reportValidity() — Devuelve un booleano y muestra la UI de error nativa
  • setCustomValidity() — Establece mensajes de error personalizados
const password = document.querySelector('#password');
const confirm = document.querySelector('#confirm');

confirm.addEventListener('input', () => {
  confirm.setCustomValidity(
    password.value !== confirm.value ? 'Las contraseñas deben coincidir' : ''
  );
});

Llama a setCustomValidity('') para limpiar errores: pasar cualquier cadena no vacía marca el campo como inválido.

Cuando la Validación Nativa se Queda Corta

La validación nativa maneja la mayoría de los casos, pero tiene límites:

  • La validación entre campos (confirmación de contraseña) requiere JavaScript
  • El estilo de los mensajes de error está controlado por el navegador
  • La validación asíncrona compleja (disponibilidad de nombre de usuario) necesita código personalizado

La estrategia: usa atributos de validación HTML como tu línea base, estiliza con CSS :user-invalid, y añade la API de Validación de Restricciones solo donde sea necesario.

Conclusión

La validación nativa de formularios ha madurado significativamente. Los atributos cubiertos aquí—form, sobrescrituras por botón, dirname, tokens modernos de autocomplete—eliminan JavaScript personalizado sustancial mientras mejoran la accesibilidad por defecto.

Audita tus formularios existentes. Probablemente encontrarás lógica de validación que HTML maneja de forma nativa, y problemas de UX que CSS :user-invalid resuelve sin un solo event listener.

Preguntas Frecuentes

Los globos de error de validación nativos tienen opciones de estilo limitadas controladas por el navegador. No puedes estilizarlos directamente con CSS. Para mensajes de error con estilo personalizado, puedes deshabilitar la UI de validación automática usando el atributo novalidate en el formulario, luego usar la API de Validación de Restricciones para verificar la validez y mostrar tus propios elementos de error. La propiedad validationMessage te da acceso al texto de error generado por el navegador.

Sí, los atributos de validación nativos funcionan en frameworks ya que renderizan HTML estándar. Sin embargo, los frameworks a menudo gestionan el estado del formulario de manera diferente, lo que puede entrar en conflicto con la validación nativa. Muchos desarrolladores usan el atributo novalidate y manejan la validación a través del estado del framework. Aún puedes aprovechar la API de Validación de Restricciones programáticamente dentro de tus componentes para un enfoque híbrido.

Ambos métodos devuelven un booleano indicando si el elemento pasa las restricciones de validación. La diferencia está en los efectos secundarios: checkValidity() solo dispara el evento invalid en caso de fallo, mientras que reportValidity() también muestra la UI de mensaje de error nativo del navegador. Usa checkValidity() cuando quieras verificar la validez silenciosamente, y reportValidity() cuando quieras que el navegador muestre retroalimentación de error a los usuarios.

No puedes validar que dos campos coincidan usando solo atributos HTML. Esto requiere JavaScript. Usa la API de Validación de Restricciones añadiendo un event listener de input al campo de confirmación, luego llama a setCustomValidity() con un mensaje de error cuando los valores difieran o una cadena vacía cuando coincidan. Esto integra tu lógica personalizada con el sistema de validación nativo.

Gain control over your UX

See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay