Gráficos de barras superpuestas | consejos CSS

Como sugiere el nombre, los gráficos superpuestos visualizan dos conjuntos diferentes de datos en un solo gráfico. La idea es que las barras superpuestas nos permitan comparar los datos, digamos, año tras año. También son útiles para cosas como el seguimiento del progreso de una meta donde una barra representa la meta y la otra muestra la cantidad actual.

¡Pero también son hermosos!

Una cuadrícula de dos por dos de ejemplos de gráficos superpuestos.

Tu mente es probablemente como la mía y ya está comenzando a descubrir cómo codificarás esto. Así es como lo abordé.

HTML

Comenzaremos con el marcado porque, bueno, así es como sabemos qué necesita estilo.

<div class="container">
  <div class="chart">
    <dl class="numbers">
      <dd><span>100%</span></dd>
      <!-- all the way to 0% -->
    </dl>
    <dl class="bars">
      <div>
          <dt>2018</dt>
          <dd>
            <div class="bar" data-percentage="50"></div>
            <div class="bar overlap" data-percentage="53"></div>
          </dd>
        </div>
      <div>
      <!-- more bars -->
    </dl>
  </div>
</div>

Usaremos listas de descripción (<dl>) porque es un enfoque mucho más semántico en comparación con las listas ordenadas y desordenadas estándar. Otra razón es que incluimos una etiqueta en cada barra. Los listados normales no contienen una etiqueta para agregar un título o descripción a diferencia de los listados de definición. En pocas palabras, tiene más sentido y también es más legible.

La primera lista de descripción, .numbers, es el eje y. los .bars es donde se visualizan los datos y también creé una lista de definiciones para construir el eje x. Cada elemento de la lista contiene un .bar y la etiqueta como término descriptivo (dt).

¿Y qué pasa con el atributo de datos? los data-percentage se utiliza para especificar la altura de la barra, que en última instancia representa su valor en el eje y. Podríamos definirlo manualmente en CSS para cada barra, pero eso es repetitivo y requiere mucho código adicional que se puede reemplazar con unas pocas líneas de CSS.

Estilos de gráficos básicos

Trabajamos con muchas direcciones bidimensionales, por lo que flexbox será nuestro amigo para alinear todo. podemos hacer el .chart elemento un contenedor flexible que coloca las etiquetas del eje y y el gráfico uno al lado del otro dentro del elemento row dirección.

.chart {
  display: flex;
}

Ni siquiera necesitamos especificar la dirección ya que flexbox es predeterminado row. Hagamos esto y luego agreguemos flexbox a la lista de etiquetas a lo largo del eje y mientras estamos en eso, porque sabemos que se ejecutarán en el column dirección.

.numbers {
  display: flex;
  flex-direction: column;
  list-style: none;
  margin: 0 15px 0 0;
  padding: 0;
}

Lo crea o no, podemos usar flexbox nuevamente para barras porque también funcionan en un row dirección.

.bars {
  display: flex;
  flex: auto; /* fill up the rest of the `.chart` space */
  gap: 60px;
}

Configuré esto para que el .bars ocupan automáticamente todo el espacio dejado por el y-axis .numbers.

Probablemente lo hayas notado en el HTML, pero "barra" son en realidad dos barras donde una se superpone a la otra. Los empaqué en un genérico <div> que podemos usar como otro contenedor flexible que contiene el término definitorio (<dt>) que usamos como etiqueta y los detalles de la descripción (<dd>) que contiene los dos valores de barra:

.bars > div {
  align-items: center;
  display: flex;
  flex-direction: column;
  flex: 1;
  position: relative;
}

Cada barra tendrá el mismo ancho, por lo que flex: 1. Estamos posicionando relativamente el elemento mientras estamos en ello porque estamos a punto de posicionar absolutamente todas las barras y queremos asegurarnos de que permanezcan en sus contenedores.

Cada barra tiene una altura porcentual que corresponde a los valores a lo largo del eje y vertical. También puede recordar que le dimos a cada barra un data-percentage atributo: agregaremos algo de JavaScript que establece la altura de cada barra usando estos valores.

var bars = document.querySelectorAll("dd .bar");
bars.forEach((bar) => {
  var height = bar.getAttribute("data-percentage");
  bar.style.height = height + "%";
});

¡Esta es nuestra placa base!

Queremos llegar a donde podamos ver las barras superpuestas. ¡Es el siguiente!

Barras apiladas

El truco para hacer que una barra se superponga a otra es divertido porque a menudo tratamos de evitar cosas para superponerse visualmente en CSS. Pero en este caso, realmente queremos que suceda.

Las barras ya se superponen; es difícil de decir. Observe en el HTML que el segundo .bar en cada juego tiene un extra .overlap clasificar. Aprovechemos esta oportunidad para diferenciar las barras. Eres completamente libre de elegir tu propio estilo para esto. Agrego un poco de relleno a la .overlap barras para que sean más anchas que las otras barras. Luego cambio el orden de apilamiento usando z-index de manera que la .overlap las barras se sientan debajo de las otras barras.

Agreguemos un título

Leyenda. Una palabra tan grande, ¿no? Repleto de todo tipo de significado. En este caso, es más que un buen toque porque visualmente estamos encajando dos barras en espacios que normalmente están reservados para una barra. Una leyenda proporciona contexto que explica lo que representa cada barra.

<figure class="legend">
  <div class="type1">Estimate</div>
  <div class="type2">Actual</div>
</figure>

Usando un <figure> me parece correcto A menudo se usan para envolver imágenes, pero la especificación dice que se usan "para anotar ilustraciones, diagramas, fotos, listas de códigos, etc.". y trabajamos con un diagrama. Probablemente podríamos usar una lista desordenada para contener los elementos, pero opté por una lista semántica desordenada. <div>. Si alguien tiene una opinión sobre la mejor manera de puntuar esto, ¡soy todo oídos en los comentarios!

De nuevo, el estilo depende de ti:

Consideraciones de accesibilidad

Dedicamos mucho de nuestro esfuerzo a tomar decisiones sobre el marcado y el estilo de nuestro gráfico de barras superpuestas. Ha sido genial hasta ahora, pero definitivamente no hemos terminado porque podemos hacer más para hacer más accesible vivir. No todos son usuarios de Internet videntes, por lo que hay trabajo adicional por hacer para transmitir contenido en estos contextos.

Más específicamente, debemos:

  1. comprobar que nuestros colores tienen mucho contraste entre ellos,
  2. permitir a los usuarios del teclado tabular en cada barra superpuesta, y
  3. asegúrese de que los lectores de pantalla anuncien el contenido.

Contrastes de color

Necesitamos suficiente contraste entre:

  • barras superpuestas
  • barras de gráfico y fondo
  • etiquetar texto y fondo

Investigué un poco de antemano sobre los colores que he usado en los ejemplos que hemos visto hasta ahora, asegurándome de que haya suficiente contraste entre los primeros planos y los planes para lograr el cumplimiento de WCAG AA.

Esto es lo que uso:

  • Barras superpuestas: (#25DEAA y #696969: relación 3,16:1)
  • Barras y fondo del gráfico (#696969 y #111: proporción 3,43:1)
  • Texto y fondo de la etiqueta del eje Y (#fff y #333: relación 12,63:1)

Tabulador entre barras

Para lograr esto, donde los usuarios del teclado pueden seleccionar cada barra individual con el Lengua clave que podemos alcanzar para HTML tabindex atributo. Podemos usar el siguiente JavaScript en la función for-each para agregar esta propiedad a cada barra (ambos). Estableceremos el índice de la pestaña en 0:

bar.setAttribute("tabindex", 0);

También podemos agregar algo de CSS para mejorar el contorno cuando se selecciona la barra mientras estamos en ella:

.bar:focus {
  outline: 1.5px solid #f1f1f1;
}

Anunciar contenido para lectores de pantalla

Otro aspecto importante de la accesibilidad es asegurar que los lectores de pantalla puedan anunciar las barras y sus porcentajes.

Estamos trabajando con dos gráficos diferentes en uno: un gráfico que muestra valores "estimados" y otro que muestra valores "reales". Sería genial si el usuario supiera qué bar se anuncia, así que etiquételos con el aria-label atributo:

<div class="bar" data-percentage="50" aria-label="Estimate">50%</div>

Tenga en cuenta que también tenemos el valor de la barra directamente en el HTML. Se anunciará, pero aún queremos ocultarlo visualmente. Podríamos usar transparent text para esto, pero otra forma es usar el clásico .visually-hidden truco envolviendo el valor en span:

<div class="bar" data-percentage="50" aria-label="Estimate">
  <span class="visually-hidden">50%</span>
</div>
.visually-hidden {
  clip: rect(0 0 0 0); 
  clip-path: inset(50%);
  height: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap; 
  width: 1px;
}

Mientras hablamos de anunciar contenido, probablemente podamos evitar que se lean las etiquetas del eje y. No es que al usuario le falte información, ya que los porcentajes reales de cada barra ya están disponibles y anunciados. Podemos usar el aria-hidden atributo para esto:

<dl class="numbers" aria-hidden="true">
  <dd><span>100%</span></dd>
  <dd><span>80%</span></dd>
  <dd><span>60%</span></dd>
  <dd><span>40%</span></dd>
  <dd><span>20%</span></dd>
  <dd><span>0%</span></dd>
</dl>

También creo que los lectores de pantalla pueden ignorar el título, ya que es una ayuda visual:

<figure class="legend" aria-hidden="true">
  <div class="type1">Estimate</div>
  <div class="type2">Actual</div>
</figure>

La demostración final

¡Es una envoltura!

¡Y ahí lo tienes, un gráfico con barras superpuestas! Es una excelente manera de comparar datos y, con suerte, puede encontrar un uso para algunos proyectos.

¿Hay otras formas de abordar esto? ¡Claro! Todo lo que hemos cubierto aquí es solo para guiarlo a través de mi proceso de pensamiento. Me imagino que algunos de ustedes habrían tomado un enfoque diferente. Si ese es usted, ¡comparta! Sería genial ver otras técnicas de diseño CSS y perspectivas sobre accesibilidad.

Si quieres conocer otros artículos parecidos a Gráficos de barras superpuestas | consejos CSS puedes visitar la categoría Estilo.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir

Esta página web utiliza cookies para analizar de forma anónima y estadística el uso que haces de la web, mejorar los contenidos y tu experiencia de navegación. Para más información accede a la Política de Cookies . Ver mas