DÍA 1 / 2017

CSS al rescate: UX y Formularios

Los formularios dieron un salto cualitativo con HTML5, los nuevos tipos de input y la validación por el navegador. Pero podemos ir un paso más allá y mejorar la UX de los mismos gracias a las pseudo-clases CSS3 y algunas pinceladas de la especificación de selectores de nivel 4.


Hablamos mucho de experiencia de usuario y de cómo mejorar las expectativas de los visitantes en nuestras aplicaciones web, sobre cómo mejorar la velocidad de carga hasta detalles concretos como el número máximo de caracteres por línea para tener textos más legibles, ubicación de elementos en el layout, etc..Pero si hay un ítem en la web que concentra todas las frustraciones del usuario ese es sin duda los formularios.

¿Dónde se produce la interacción del blogger con sus seguidores? En el formulario de comentarios. ¿Dónde puedo contarte una sugerencia sobre tu web? En el formulario de contacto ¿Cómo puedo saber cuanto me costará el proyecto que tengo en mente? En el formulario de petición de presupuesto…

Por suerte con las especificaciones HTML5 para los formularios y sus campos hemos conseguido mejorar y ser más específicos en las definiciones que hacíamos, incluso tener una validación al enviar el form gracias al navegador sin necesidad de usar JS. Pero aún podemos ir más allá y facilitarle la vida al usuario con comentarios y validación en vivo, y todo con CSS!

Conociendo las herramientas que vamos a utilizar.

Creo que es bueno exponer antes toda la parte teórica y definir los elementos que vamos a utilizar en este artículo. Si solo vienes a por el código, ve directamente al ejemplo del final, aunque te recomiendo que primero leas esta introducción para así comprender bien todo el recorrido que vamos a hacer. Seguro que aprendes algo nuevo!

input y textarea

Empezamos por lo básico. Los elementos input y textarea definirán nuestros campos del formulario. textarea lo utilizaremos para el campo donde los usuarios puedan exponer sus sugerencias o dentro de un blog para el campo donde dejar el comentario.

En cuanto al elemento input, hay varios tipos, y esto es importante, cada uno con una regla de validación y formato por defecto. Para este ejemplo utilizaremos tres tipos:

<input type="text"> <!-- Para el nombre y el apellido -->
<input type="email"> <!-- Para recoger correo electrónico -->
<input type="url"> <!-- Para preguntar por un sitio web -->

Hay muchos tipos mas, aquí tienes el listado completo: https://www.w3.org/TR/html/sec-forms.html#element-attrdef-input-type

required

Atributo válido para los elementos input y textarea. Indica que son campos requeridos y que deben rellenarse antes de enviarse el formulario. Está directamente relacionado con la pseudo-clases :required y :optional, de las que hablaremos más adelante.

En nuestro caso por ejemplo, el campo email será obligatorio y vendrá definido por:

<input type="email" required>

pattern

Atributo que podemos utilizar para establecer un patrón válido para cada input. Por defecto, los inputs tienen una validación definida por su tipo, email buscará dirección de email, tel teléfonos, en url solo serán válidas las direcciones de sitios web…

Pero podemos ir más a allá y crear nuestros propios patrones o establecer otras reglas, como longitudes mínimas y máximas de caracteres. Un ejemplo sencillo, un input de tipo texto como el del ejemplo de este artículo, para introducir el nombre, que permite cualquier carácter menos números (nadie se llama 11 o 432) y así de camino ponerlo un poco más difícil a los spammers. El atributo pattern en este caso sería:

<input type="text" pattern="^[^0-9]+$" required>

El atributo pattern requiere de una expresión regular [RegExp]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp y su compatibilidad es práctimente total en los navegadores actuales: http://caniuse.com/#feat=input-pattern.

placeholder

El atributo placeholder es uno de los más útiles a la hora de definir la UX de nuestros formularios. Nos permite mostrar un valor por defecto a modo de ejemplo o alguna pista sobre cómo rellenar el input que será automáticamente ocultado cuando el usuario escriba un caracter en el campo seleccionado.

Esto es importante tenerlo en cuenta. Hacer :focus en el input no hace que el placeholder se oculte. Solo cuando escribimos el valor del placeholder desaparecerá. Jugaremos con esto en nuestro ejemplo.

::placeholder

Pseudo-elemento ligado al atributo anterior, que nos permite darle estilo. Podemos definir por ejemplo un color más claro para el texto del placeholder, para diferenciarlo del texto que ha introducido el usuario. La compatibilidad de este pseudo-elemento es buena siempre que usemos nombres alternativos para cada navegador: http://caniuse.com/#feat=css-placeholder

Así ::placeholder definirá el estilo para los las versiones de navegadores actuales, mientras que ::-moz-placeholder, ::-webkit-input-placeholder y :-ms-input-placeholder nos asegurará una buena compatibilidad en versiones menos recientes.

Vamos con las pseudo-clases!

:focus

Pseudo-clase básica que se aplica al elemento o elementos que son actualmente foco por parte del usuario. En nuestro caso cuando el usuario ha hecho clic en un input o ha navegado con el teclado hasta él.

Hablábamos antes de si al hacer focus en un campo haría que el texto placeholder desareciese. La respuesta era no, necesitábamos que el usuario introdujese algún caracter para que esto ocurriese. Pero ahora tenemos dos opciones de dar estilo al texto del placeholder, cuando el usuario no está haciendo focus sobre el campo con input::placeholder, y cuando sí está haciendo focus pero todavía no ha escrito nada con input:focus::placeholder.

:valid

El pseudo-selector :valid asociado a un elemento <input> nos va a permitir conocer si los contenido introducido concuerda con los patrones o valores admisibles para dicho form. Para entenderlo de una forma sencilla, si estamos rellenando un <input type="email">, el valor no será válido hasta que introducimos un contenido en formato email, tipo nombre@dominio.com (aunque el .com no está marcado en el patrón por defecto de este tipo de input).

También podíamos hacerlo más restrictivo, con un patrón de solo letras, y el guión o espacios para nombres compuestos. Además limitar una longitud mínima, por ejemplo 2 caracteres, por si alguien se llama Fé o utiliza un diminutivo tipo AJ.

El caso es que en el momento que todas las condiciones se cumplan, podemos dar estilo usando esta pseudo-clase. Tendremos la seguridad de que el valor introducido es válido!

:invalid

Esta pseudoclase hace todo lo contrario, estará activa mientras los valores introducidos no sean válidos. Muy útil tanto para cuando el usuario está escribiendo como para cuando pase al siguiente input y poder marcar de alguna forma que el contenido introducido no es válido.

¿Y qué pasa si no se ha introducido ningún valor? Pues el atributo required será el encargado de decidir si el input es válido o no. Si existe el atributo, es decir el campo es obligatorio, sin haber introducido nada nos marcará como :invalid. En cambio si el campo no tiene el atributo required, quiere decir que es opcional, al dejarlo vacío nos servíará :valid.

Tanto las pseudo-clases :valid e :invalid como los :required y :optional que sirven para dar estilo a aquellos campos que son obligatorios o no, se encuadran dentro del grupo de las pseudoclases de validación de formularios, y su compatibilidad entre navegadores nuevamente es bastante amplia: http://caniuse.com/#feat=form-validation.

:placeholder-shown

Bueno pues aquí conocemos una nueva pseudo-clase todavía en borrador para la especificación de selectores de nivel 4, pero con una compatibilidad bastante aceptable entre navegadores (excepto IE y Edge): http://caniuse.com/#feat=css-placeholder-shown.

Se trata de una pseudo-clase que está activa siempre que el placeholder esté visible. Es decir, nos permite dar estilo al elemento input cuando el campo no está :focus y cuando está :focus pero el usuario no ha comenzado todavía a escribir (recuerda que el placeholder no desaparece hasta que el usuario no escriba nada).

Esta pseudo-clase es muy útil, pues junto con las anteriores nos va a permitir tener un control total no solo sobre los estados del elemento input, sino conocer en todo momento si el usuario aún no ha hecho clic sobre el campo, si ha hecho :focus pero no sabe que escribir o si ya ha comenzado a escribir, pudiendo ayudarle o mostrarle información extra en cualquiera de esos casos.

Por ejemplo, el usuario ha hecho input pero no sabe qué escribir. Podemos esperar 5 segundos para mostrarle un mensaje de ayuda (si, solo CSS!). O ha comenzado a escribir, lleva 15 segundos y el campo todavía es :invalid. Quizás no sepa qué patrón ha de seguir, podemos mostrarle un aviso de las normas de ese campo (longitud mínima o que no admite números…).

Cómo ves el abanico de opciones es muy amplio, con estas herramientas solo hay que tener un poco de creatividad y ponernos en la piel del usuario para mejorar su experiencia a la hora de rellenar nuestros formularios. Vamos a verlo con un ejemplo.

Poniendo todo en práctica: Formulario con validación CSS.

Para el ejemplo hemos utilizado un form sencillo formado por dos inputs de texto, uno para el nombre y otro para el apellido, un campo para el email, otro para el sitio web y un textarea para que el usuario pueda dejarnos sus comentarios o sugerencias. Finalmente un input tipo submit para enviar dicho form.

See the Pen UX Forms. HTML5 + CSS3 (and a bit of CSS4) by Ricardo Prieto (@ricardpriet) on CodePen.dark

Un formulario que nos podría valer para recoger los comentario de un blog o una sección de contacto para que los usuarios puedan enviar sus sitios web o portfolios. Sea como fuere, hemos establecido 4 elementos obligatorios (Nombre, Apellidos, Email y Comentario), dejando uno opcional (Dirección web).

Todos los campos tienen su placeholder, pero al hacer :focus en ellos este cambia de color a transparente, y ubicamos el label en la parte superior del campo, para que el usuario siempre tenga presente la información del campo está rellenando. Hemos diferenciado el contenido del label y del placeholder a propósito para que puedas ver la diferencia.

En el momento en que un campo sea válido, el borde y el color del texto del label se tornará a verde, indicándonos que podemos pasar a otro input. Al cambiar de campo, el fondo se coloreará de un verde dando por sentado que dicho campo está ok. Es decir, cuando ya no estemos :focus pero el campo sea :valid.

De forma contraria, cuando estemos rellenado un campo y lo abandonemos con un contenido :invalid, este tornará el fondo a otro color de alerta para avisarnos que debemos volver a él para completarlo.

¿Necesitamos una ayuda extra? Hemos incluido un atributo data-help en cada una de los labels, atributo que será recogido como contenido del pseudo-elemento :after, para mostrarse al lado del texto del label. ¿Cuándo lo mostraremos? Mediante una animación CSS que dura 100 segundos, ocultaremos el mensaje los 4 primeros, para mostrarlo en el segundo 5.

Para este ejemplo no hemos realizado distinción entre si el usuario ha escrito algo o todavía nada. Siempre que el campo sea invalid y hayan pasado más de 5 segundos, el usuario tendrá nuestra ayuda. Te dejo como ejercicio el código para mostrar el data-help solo en caso de que el usuario no haya escrito nada todavía, o que haya empezado a escribir hace X segundos.

En un caso en producción lo bueno sería alargar este tiempo a 10s o 15s, pero como no te quiero hacer perder mucho tiempo buscando los data-help que hemos utilizado, con 5 segundos creo que va bien para el ejemplo 🙂

Finalmente un dato curioso. El campo url, que por cierto tiene un patrón por defecto algo restrictivo (las urls deben empezar por http:// o https://), lo hemos marcado como opcional. Si queda vacío es bien, pero si aplicamos el estilo de :valid al mismo, nos lo marcará como válido estando vacío. No queremos eso, es opcional, pero si el usuario lo rellena mejor que mejor. Para ello, si no está :focus, ni tiene contenido, estilo neutro.

Espero que te haya servido la información para hacer la vida más sencilla a los visitantes y mejorar la experiencia de usuario a la hora de rellenar formularios, esos grandes olvidados del diseño web. Mucha CSSuerte!