HTML5 nos permite definir patrones de validación para los diferentes campos de un formulario sin utilizar ni una sola línea de javascript. Esta característica nos permite ahorrarnos algunas solicitudes inadecuadas y el consiguiente gasto innecesario de recursos del servidor, aunque sin duda la principal ventaja es la mejora de la experiencia del usuario.

Es importante anotar que la validación de formularios con HTML5, al igual que la validación con javascript, se realiza en el lado del cliente (navegador web) y, por tanto, puede ser modificada por el usuario o ignorada totalmente. Esto quiere decir que las cuestiones relativas a la seguridad del formulario no deben basarse en esta validación ni es sustituta de la validación server-side.

Métodos de validación de formularios con HTML5

HTML5 ofrece diferentes métodos de validación de formularios client-side utilizando diferentes atributos para el elemento <input>. Los más destacados son type, pattern y required. Veamos cada uno de estos atributos y ejemplos de uso. Las imágenes ilustrativas son obtenidas utilizando el navegador firefox y pueden variar si se utiliza otro navegador.

El atributo type

Con el atributo type indicamos al navegador el tipo de control que debe ejercer sobre el elemento <input>. Ya en HTML4 nos acostumbramos a <input type="text" /> pero a partir de HTML5 podemos utilizar una amplia gama:

  • color
  • date
  • datetime
  • datetime-local
  • email
  • month
  • number
  • range
  • search
  • tel
  • time
  • url
  • week

Si los datos introducidos en el campo del formulario no coinciden con el tipo especificado, el navegador lanzará un aviso al usuario y el formulario no se enviará. Por ejemplo, podemos requerir que se introduzca una dirección de correo electrónico:

<input type="email" name="email">

Dará el siguiente aviso si se introduce un email no válido:

HTML5 email
Validación email con HTML5 type=”email”

Es el propio navegador el que valida los datos introducidos según el tipo especificado. La validación para algunos valores de type puede ser muy diferente de unos países a otros y por ello algunos tipos no son universalmente soportados. Por ejemplo, el type="tel", utilizado para números de teléfono, necesita un patrón de validación diferente para diferentes países y regiones. La solución para seguir con HTML5 y no utilizar javascript es definir patrones de validación propios con el atributo pattern.

El atributo pattern

Este atributo es sencillamente espectacular. Nos permite definir patrones de validación client-side personalizados sin prácticamente límite. El valor de este atributo ha de ser un formato de datos con notación de expresión regular javascript. Las expresiones regulares, conocidas como regex (del inglés regular expression), son incluidas en prácticamente todos los lenguajes de programación y permiten validar una cadena de texto frente a palabras, caracteres y patrones de una forma muy flexible a la vez que concisa.

Al poner un regex como valor del atributo pattern en un <input> decimos al navegador cuál es el valor aceptable para este campo del formulario. Familiarizarse con las expresiones regulares puede llevar algún tiempo y práctica, puedes empezar con la documentación para regex en javascript ofrecida por mozilla.

Por ejemplo, en España un número de teléfono fijo comienza por 9 o por 8 y un número móvil comienza por 6 o por 7 y en ambos casos le sigue un número de 8 dígitos. Un regex para aceptar números de teléfono de España podría ser:

<label for="tel">Teléfono (9 dígitos comenzando por 9, 8, 7 o 6)</label>
<input type="text" pattern="^[9|8|7|6]\d{8}$">

Este regex dice: aceptar sólo un número que comiencen por 9, 8, 6 o 7 seguido de 8 dígitos. En caso de introducir un número incorrecto saldría el siguiente aviso:

Validación teléfono español con HTML5
Validación teléfono español con HTML5 y el atributo pattern
Para utilizar el atributo pattern es recomendable utilizar el type="text" y no un type de los predefinidos en HTML5 que ya cuentan con patrones de validación en el propio navegador. Mezclar ambos puede llevar a resultados inesperados.

Personalizar avisos con el atributo title

En los ejemplos anteriores los avisos mostrados eran elegidos por el navegador. A través del atributo title podemos personalizar estos avisos. Por ejemplo:

<input type="text" name="twitter_username"
       pattern="^@?(\w){1,15}$"
       title="Este no parece un usuario de twitter válido">

Con el pattern anterior se aceptaría una cadena de texto de 15 letras que no contenga caracteres especiales (ñ, vocales acentuadas, etc). La cadena puede comenzar por @ o no. Con esta regla se aceptarían sólo nombres de usuario de twitter válidos y se lanzaría el siguiente aviso personalizado si se introduce uno no válido:

Validación usuario twitter con HTML5
Validación usuario twitter con HTML5 y el atributo pattern con aviso personalizado

El atributo required

Tal y como su nombre indica, este atributo se utiliza para decir al navegador los campos del formulario que son requeridos de forma obligatoria, es decir, que no pueden quedar vacíos. Basta con poner required o required="required". Por ejemplo:

<input type="text" name="twitter_username"
       pattern="^@?(\w){1,15}$"
       title="Este no parece un usuario de twitter válido"
       required>

Si el <input> anterior se deja vacío se mostrará el siguiente aviso:

required HTML5
Aviso de campo obligatorio con atributo required en HTML5

Recuerda que:

  • La validación de formularios con HTML5 ahorrará bastante trabajo de desarrollo al no tener que validar con javascript
  • El soporte entre distintos navegadores está bastante extendido, salvo algunos tipos que requieren la especificación de expresiones regulares para su validación
  • A través del atributo pattern las posibilidades son infinitas y podemos validar cualquier formato de datos que deseemos
  • La seguridad de la validación con HTML5 es igual que la seguridad de la validación con javascript: ninguna. Ambas son validaciones client-side y nunca deben sustituir la validación server-side
  • Efrain Gomez

    Hola..
    Necesito validar una caja de texto “textarea” que cuando le de espacio no la valide

  • Roberto P.

    Hola yo tengo un formulario hecho en html5 y validado con php, pero al parecer los campos que contienen el atributo required no sirven en dispositivos móviles, cómo se puede arreglar eso? Agradeceré tu ayuda

    • Hola Roberto.

      El soporte del atributo required es parte del HTML y como tal no depende del dispositivo sino más bien del navegador que utilices. Por ejemplo, el navegador Safari no soporta este atributo en ninguna versión pero si pruebas Google Chrome o Mozilla Firefox en tu móvil podrás comprobar como sí funciona.

      Si quieres asegurarte de que el atributo required funciona en cualquier navegador, no te queda más remedio que seguir con los métodos anteriores a la existencia de este atributo basados en JavaScript.

    • maxi g.

      tengo el mismo problema que roberto y en el movil utilizo el chrome del movil y esto me he dado cuenta que no funciona solo en android yaq en ios si me respeta los filtros que puedo hacer para que también me respete los filtros en android ?

    • A Roberto no le funcionaba el atributo required pero tu hablas de “filtros”, así que no se si será el mismo problema. En principio, te doy la misma respuesta.

      Visita el enlace que le pasé en esa respuesta, ahí puedes ver las versiones de cada navegador en las que el atributo required es soportado. En el caso de Chrome para Android es a partir de la versión 51.

  • Juan Simón

    Hola, tengo una duda… Yo tengo mi formulario y necesito que en el input “nombre y apellido” solo se acepte texto, si se coloca un número de error. He buscado pero no ha dado frutos mi búsqueda.

    • Utiliza un <input type="text"> con un pattern que no incluya números.

    • Juan Simón

      Gracias, me sirvió 😀

  • Felipe

    ¿Cómo sería el pattern para el NIE (DNI/NIE/CIF)?

  • victor

    ¿como seria para las targetas de credito?
    y cuando se vence la targeta

  • yoselin

    El atributo pattern funciona de la misma manera en cualquier navegador?

  • samuel

    Muy buen tutorial! me ayudo de mucho!! gracias.