Saltar a contenido pricipal

En defensa del div

En el mundo de la accesibilidad web el div es percibido como el Nickelback de los elementos HTML. Genérico, aburrido y sin significado. Esto último es muy importante. Uno de los pilares de un sitio accesible es el HTML semántico. Es decir, utilizar elementos debido a su significado, y no su presentación visual. Teniendo en cuenta eso, el div, al carecer de significado semántico suele ser mal visto. Usado casi con vergüenza. No obstante, en una gran cantidad de casos su uso es completamente válido y hasta preferible.

La idealización del HTML semántico

Toda persona que decide involucrarse en la accesibilidad web aprenderá sobre la importancia de la semántica. Es accesibilidad 101, de lo primero que se aprende. Sin embargo, he notado que esa importancia a veces suele ser exagerada o mal interpretada.

He visto muchos casos en los que se pierde un montón de tiempo buscando el elemento perfecto para que todo sea semántico, evitando el uso de un div a toda costa. Esto puede resultar en un abuso de etiquetas que no cumplen ninguna función con beneficio real, o que terminan contaminando la página con redundancias en nombre de la semántica.

¿Cuándo es importante la semántica?

Es vital comprender el motivo por el cuál es importante, para así saber cuando no lo es.

¿Qué es esto?

Permite a usuarios de tecnología de asistencia como un lector de pantalla saber con qué elemento están interactuando. Los elementos como un botón, enlace o encabezado tienen un rol implícito que le permiten al usuario saber lo que es. Otros elementos como fieldset y legend ayudan a comunicar una asociación.

Accesibilidad gratuita

Un elemento nativo viene con funcionalidades de accesibilidad por defecto. Un botón por ejemplo es enfocable con un teclado, puede ser activable usando las teclas space y enter, y tiene un rol que le comunica a un lector de pantalla que es un botón. Si usaras otro elemento como un div tendrías que ofrecer esta funcionalidad tú mismo.

Puntos de referencia

HTML5 introdujo elementos que ayudan a dar estructura a la página y sirven como puntos de referencia, o áreas reconocibles dentro de la página. Estos puntos de referencia son conocidos en inglés como landmarks, y funcionan como atajos para acceder a distintas partes importantes del sitio, o evitar otras secciones redundantes como la navegación principal.

Semántica sin sentido

El mayor abuso de etiquetas semánticas ocurre al crear la estructura de la página y definir los puntos de referencia o landmarks. Como buena práctica, es importante que todo el contenido se encuentre dentro de un landmark. Así el usuario tiene rápido acceso a las secciones importantes del sitio.

Esto no significa que debamos llenar una página con todos los puntos de referencia que se nos ocurra y en grandes cantidades. Al contrario, resulta perjudicial. Un punto de referencia es una sección importante de la página. Y cuando hay un exceso de puntos de referencia estamos indicando que todo es importante. Y si todo es importante, nada lo es realmente. Solo lograrás contaminar la lista de landmarks que el usuario tiene que navegar para llegar a donde quiere.

En una gran cantidad de casos usar una sola instancia de header, main, footer y aside será suficiente. Sumado a las instancias necesarias de nav que por lo general no serán más de 2 o 3.

Ejercicio de semántica

Hagamos un ejercicio. Tienes que crear una lista de 3 artículos de un blog en una sección de la página de inicio. ¿Cómo estructurarías el HTML?

Es una sección dentro de la página con contenido temático, un grupo de artículos de blog. Por lo tanto un elemento section podría ser apropiado. Si es una sección, usualmente también tiene un encabezado. En este caso de nivel 2 porque estás describiendo una sección nueva. Recordemos que es una lista de artículos, por tanto usar una lista no ordenada tendría sentido. Un artículo de un blog es contenido distribuible o reutilizable de manera independiente, y por tanto el elemento article es semánticamente correcto. Y para finalizar, cada artículo tiene un título, que en este caso sería un encabezado de nivel 3 porque es una subsección de la sección de artículos. El código se vería así:

<section>
  <h2>Últimos artículos</h2>
  <ul>
    <li>
      <article>
        <h3><a href="#">En defensa del div</a></h3>
      </article>
    </li>
    <li>
      <article>
        <h3><a href="#">Entendiendo las regiones vivas</a></h3>
      </article>
    </li>
    <li>
      <article>
        <h3><a href="#">Windows con alto contraste</a></h3>
      </article>
    </li>
  </ul>
</section>

Esto se podría considerar semánticamente correcto, pero antes de explicar por qué es innecesario es importante entender algunos de sus elementos.

Section

Según la especificación de HTML, el elemento section representa una sección genérica de un documento o aplicación. Y en ese contexto es una agrupación temática de contenido, típicamente con un encabezado.

Teniendo en cuenta eso, cuál es el aporte del elemento en términos de accesibilidad? Un section no es identificado como un punto de referencia a menos que tenga un nombre accesible, y en ese caso queda expuesto el rol region. O sea, si no cuenta con un nombre accesible no es mejor ni peor que ese div que tanto estás intentando evitar. No obstante, digamos que decides darle un nombre accesible utilizando aria-labelledby:

<section aria-labelledby="articulos">
  <h2 id="articulos"><a href="#">Últimos articulos</a></h2>
</section>

La pregunta ahora es, ¿es necesario? Ya tienes un encabezado de nivel 2 que describe la sección. Si tienes una buena estructura de encabezados en la página, el usuario ya tiene cómo acceder ahí con un atajo. Esto no significa que no pueda ser usado, pero es importante evitar el uso excesivo. No es necesario utilizar 10 section y contaminar la lista de landmarks. Si el contenido ya cuenta con un encabezado, es momento de pensar si realmente necesitas un section o estás intentando agregar semántica porque sí.

A pesar de que en mi opinión el elemento section es ese compañero de curso que no participa en el trabajo grupal pero de todas formas pone su nombre en el informe. También pienso que tiene utilidad. Personalmente lo utilizo cuando necesito un landmark genérico. Un ejemplo de esto es al crear una tabla responsiva con desplazamiento horizontal. En ese caso es necesario usar un contenedor con el atributo tabindex="0" para que sea enfocable y así el desplazamiento horizontal sea accesible usando el teclado. Sin embargo, si algo recibe foco debe tener un rol y nombre accesible para cumplir con el criterio de conformidad 4.1.2 Nombre, función, valor (en inglés). Y como ningún otro rol cumple con lo que busco, el genérico y aburrido section o un div con role="region" es apropiado.

Article

Según la especificación de HTML, el elemento article representa una composición autónoma en un documento, página, aplicación o sitio. Es contenido que es distribuible o reutilizable de manera independiente. Ejemplos de esto son un artículo de blog o un comentario de un usuario.

A diferencia de section, este elemento no tiene el potencial de convertirse en un punto de referencia al darle un nombre accesible. Aunque VoiceOver si lo incluye en la lista de landmarks cuando abres el rotor (Ctrl + Option + u), incluso sin contar con un nombre accesible. NVDA/Chrome y JAWS/Chrome en tanto no lo incluyen en la lista de puntos de referencia, pero NVDA sí anuncia su presencia al leer la página.

En cuanto a su uso en el ejercicio, es perfectamente válido utilizar el elemento, idealmente utilizando aria-labelledby para asociarlo con el encabezado y así darle un nombre único que lo diferencie de los demás. Su uso sin embargo no es esencial ni necesario.

Solución alternativa

En términos semánticos, el código ejemplo de la lista de artículos es completamente válido. Pero es importante además crear un buen balance entre semántica y la verbosidad adicional que puede generar. Si tienes una buena estructura de encabezados, y la sección cuenta con uno, el section no es necesario. Si ya tienes un encabezado y una lista, el article también contribuye a darle verbosidad y "ruido" adicional. El siguiente código es perfectamente accesible y válido:

<div>
  <h2>Últimos artículos</h2>
  <ul>
    <li>
      <h3><a href="#">En defensa del div</h3></a>
    </li>
    <li>
      <h3><a href="#">Entendiendo las regiones vivas</h3>
    </li>
    <li>
      <h3><a href="#">Windows con alto contraste</h3>
    </li>
  </ul>
</div>

Incluso podríamos eliminar el encabezado de nivel 3. Un encabezado para la sección y una lista con enlaces también es suficiente.

Conclusión

Tu sitio no será menos accesible porque decidiste usar un par de div. No es necesario pasar una hora mirando la especificación tratando de justificar el uso de un elemento que crees es más semántico sólo porque quieres evitar el uso de un div.

Si necesitas un contenedor o darle estilos a alguna sección o componente, un div es perfectamente aceptable. Utiliza los landmarks con intención y de manera limitada para evitar verbosidad. No es necesario llenar la página con ellos en nombre de la semántica y buenas prácticas solo porque sí.