> Manuales > Tutorial de CSS básico

Explicaciones detalladas de las pseudo-clases de CSS :focus y :focus-within, con ejemplos y consejos de cara a la mejora de la experiencia de usuario y la accesibilidad de las páginas web.

Las pseudoclases :focus y :focus-within

En el mundo del diseño y desarrollo web, las hojas de estilo en cascada (CSS) desempeñan un papel fundamental y a la vez esencial. Siempre decimos que CSS es muy fácil de usar y creo que lo hemos demostrado a lo largo del Manual de CSS, pero siempre hay cosas nuevas que aprender.

En este artículo queremos seguir avanzando en las CSS, con el estudio algunas de las pseudo-clases más importantes y útiles de cara a la accesibilidad y la mejora de la experiencia de usuario.

Qué son las pseudoclases

Para quien no lo conozca las pseudoclases permiten especificar estilos en los elementos, pero no en su estado común sino en estados particulares. Tenemos pseudo-clases para definir estilos ante estados de los elementos, por ejemplo cuando el elemento tiene el ratón encima, cuando el foco de la aplicación está en un elemento o cuando el elemento está activo.

Se trata de una de las características poderosas y versátiles de CSS, a veces no tan conocidas. En este artículo vamos a ver ejemplos de pseudo-clases que vamos a usar para especificar estilos cuando el foco de la aplicación esté en un elemento o dentro de las interfaces que haya en un elemento.

Cómo usar las pseudoclases

Para usar las pseudoclases simplemente tenemos que añadir una palabra clave al selector CSS. Esa palabra especificará el estado especial que tendrá el elemento para que sea seleccionado.

Las pseudoclases siempre comienzan con dos puntos, para diferenciarlas de otros selectores, como :focus. Por ejemplo podemos seleccionar los elementos enlace <a> para aplicarle estilos solamente cuando tenga el foco de la aplicación:

a:focus {
    border: 2px solid blue;
}

Existen dos pseudoclases importantes y útiles para aplicar estilos cuando tenemos el foco de la aplicación sobre determinados elementos, que vamos a ver en este artículo, :focus y :focus-within.

La Pseudoclase :focus

La pseudoclase :focus se utiliza para seleccionar un elemento que tiene el foco de la aplicación. Para aclararnos, podemos decir que un elemento recibe el foco de la aplicación cuando el usuario hace clic en él, lo toca en pantallas touch o lo selecciona con una combinación de teclas, principalmente con la tecla de tabulación en un teclado, que nos permite ir de un elemento al siguiente.

Cuando mencionamos "el foco de la aplicación" nos referimos por supuesto también al foco del usuario dentro de los elementos de una página web.

Es muy importante que se destaque el foco porque mejora la accesibilidad de los documentos web y las aplicaciones en general. Para aquellas personas que trabajan solamente con el teclado es clave que se muestre dónde está el foco de una manera destacada. Pero además es muy útil para mejorar la experiencia del usuario, ya que permite al diseñador resaltar visualmente el elemento con el que el usuario está interactuando en un momento dado.

Un ejemplo de su uso de :focus sería cambiar el color de fondo de un campo de entrada de formulario cuando este tiene el foco:

input:focus { 
    background-color: lightyellow;
}

En el código anterior, cuando un campo de entrada input está enfocado, su color de fondo se cambia a amarillo claro.

La Pseudoclase :focus-within

Por otro lado, la pseudoclase :focus-within se utiliza para seleccionar un elemento que contiene otro elemento con el foco. En otras palabras, esta pseudoclase permite la aplicación de estilos a un elemento padre cuando cualquier elemento hijo recibe el foco.

Esta pseudoclase es de gran utilidad cuando se quiere dar una retroalimentación visual en el nivel del contenedor, como resaltar toda una sección de un formulario cuando uno de sus campos está siendo cumplimentado.

Aquí hay un ejemplo de cómo se puede utilizar :focus-within:

.interfaz-busqueda:focus-within { 
    border: 2px solid blue; 
} 

En este caso, estamos asignando el borde azul a un elemento de la clase .interfaz-busqueda que contenga un elemento que a su vez tenga el foco. Esto incluiría situaciones en las que un elemento de entrada (input) dentro de ese elemento está enfocado.

Por qué necesitamos :focus-within

No sé si salta a la vista la necesidad de esta pseudo clase. Me gustaría verlo con un ejemplo más desarrollado para que quedase muy claro.

Vamos a tener una interfaz de búsqueda que queremos implementar con un campo de texto y un icono como la que aparece en la siguiente imagen:.

Interfaz de búsqueda sin :focus-within

El HTML utilizado sería el siguiente:

<div class="busqueda">
  <section>
    <input type="text" name="buscar" id="buscar">
  </section> 
  <span>
    <svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="M796-121 533-384q-30 26-69.959 40.5T378-329q-108.162 0-183.081-75Q120-479 120-585t75-181q75-75 181.5-75t181 75Q632-691 632-584.85 632-542 618-502q-14 40-42 75l264 262-44 44ZM377-389q81.25 0 138.125-57.5T572-585q0-81-56.875-138.5T377-781q-82.083 0-139.542 57.5Q180-666 180-585t57.458 138.5Q294.917-389 377-389Z"/></svg>
  </span>
</div>

Ahora podemos ver el CSS utilizado para colocar los elementos tal como aparecía en la imagen anterior.

* {
  box-sizing: border-box;
}
body {
  font-family: tahoma;
}
.busqueda {
  background-color: #eee;
  width: 100%;
  border-radius: 1rem;
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  padding: 0.1rem 0.9rem 0.1rem 0.3rem;
  gap: 0.8rem;
}
.busqueda svg {
  width: 24px;
}
.busqueda input {
  height: 32px;
  line-height: 32px;
  width: 100%;
  border: none;
  background-color: transparent;
  padding: 0 0.5rem;
}

El problema que seguramente habremos percibido es que queda un poco feo cuando el foco está en nuestro input, porque se ven un poco las tripas de la interfaz. Lo ideal sería que, al poner el foco en el input se iluminase todo el contenedor. El efecto quedaría como esta imagen.

Ahora la misma interfaz de búsqueda usando :focus-within

El HTML para este segundo caso sería exactamente el mismo. Simplemente tenemos que cambiar un par de cosillas en el CSS.

Primero vamos a colocar la pseudoclase :focus-within para nuestro elemento de búsqueda.

.busqueda:focus-within {
  border: 2px solid blue;
}

De este modo, cuando el foco de la aplicación esté en el elemento input que hay dentro de la interfaz se pondrá el borde azul en la caja de búsqueda completa.

Además tenemos que cambiar el estilo al input, para quitar el borde de la caja de texto cuando tenga el foco, con outline: none.

.busqueda input {
  height: 32px;
  line-height: 32px;
  width: 100%;
  border: none;
  background-color: transparent;
  padding: 0 0.5rem;
  outline: none;
}

Por supuesto, usar outline: none en un campo input sin implementar otra manera de destacar que ese elemento tiene el foco, es una idea fatal de cara a la usabilidad. Por eso es importante usar en este caso el :focus-within en el contenedor padre, para que, quitar el borde al input no impacte negativamente en la experiencia de usuario y la accesibilidad.

Conclusión

Las pseudoclases :focus y :focus-within son muy importantes porque ofrecen a los diseñadores y desarrolladores web herramientas para mejorar la accesibilidad y la experiencia del usuario en sus sitios y aplicaciones web.

Permiten destacar visualmente los elementos con los que los usuarios están interactuando, proporcionando una retroalimentación inmediata y clara al usar las interfaces. Aunque pueden parecer pequeños detalles, su correcto uso puede tener un impacto significativo en la facilidad de uso y la accesibilidad de un sitio web.

Miguel Angel Alvarez

Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...

Manual