Advertisement
  1. Web Design
  2. HTML/CSS
  3. HTML Templates

Gráficos en CSS: cómo crear un organigrama horizontal

Scroll to top
Read Time: 12 min

() translation by (you can also view the original English article)

En un tutorial anterior, aprendimos cómo crear un organigrama vertical usando solamente CSS. Hoy, a petición de algunos, analizaremos el proceso de construcción de su versión horizontal correspondiente.

Y ahora viene lo bueno: vamos a crear este nuevo gráfico sin cambiar una sola línea del marcado del original; solo vamos a modificar los estilos.

Ten en cuenta que, ya que el concepto sigue siendo el mismo, vamos a tomar algunas partes del otro tutorial. ¿Estás listo para poner a prueba tus habilidades de CSS nuevamente?

El organigrama que vamos a crear

Este es el gráfico en CSS que vamos a crear:

En pantallas de hasta 1300px de ancho, el gráfico se mostrará mediante el uso de un diseño vertical. En pantallas más grandes, sus datos se mostrarán horizontalmente. Asegúrate de verificar este comportamiento abriendo la demostración en una pantalla grande y cambiando el tamaño de la ventana de tu navegador.

1. Especifica el contenedor

Nuestro gráfico residirá en el interior de un contenedor:

1
<div class="container">
2
  <!-- Chart goes here -->
3
</div>

2. Define algunos estilos básicos

Antes de examinar sus niveles, vamos a crear algunas reglas de restablecimiento y algunas clases auxiliares:

1
:root {
2
  --level-1: #8dccad;
3
  --level-2: #f5cc7f;
4
  --level-3: #7b9fe0;
5
  --level-4: #f27c8d;
6
  --black: black;
7
}
8
9
* {
10
  padding: 0;
11
  margin: 0;
12
  box-sizing: border-box;
13
}
14
15
ol {
16
  list-style: none;
17
}
18
19
body {
20
  margin: 50px 0 100px;
21
  text-align: center;
22
  font: 20px/1.5 "Inter", sans-serif;
23
}
24
25
h1,
26
h2,
27
h3,
28
h4 {
29
  font-size: inherit;
30
}
31
32
.container {
33
  max-width: 800px;
34
  padding: 0 10px;
35
  margin: 0 auto;
36
  display: grid;
37
  align-items: center;
38
  justify-content: center;
39
  grid-column-gap: 20px;
40
  grid-template-columns: auto auto;
41
}
42
43
.rectangle {
44
  position: relative;
45
  padding: 20px;
46
  width: 200px;
47
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.15);
48
}

Observa la clase rectangle. Vamos a agregar esta clase a cada nodo o elemento de nuestro gráfico.

Además, presta atención a los estilos del contenedor. Gracias a CSS Grid, podemos dividir el gráfico en dos partes. La primera parte incluirá al primer nivel, mientras que la segunda incluirá a todos los demás. Además, asignaremos al contenedor un ancho máximo que surtirá efecto solamente en pantallas más pequeñas.

The parts of chart containerThe parts of chart containerThe parts of chart container

Nota: en aras de la simplicidad, no he optimizado el CSS. Esto te ayudará a comprender mejor los estilos de cada nivel.

3. Especifica los niveles

En este punto veremos más de cerca los niveles del gráfico. Como recordarás del tutorial anterior, tendremos cuatro niveles:

The chart levelsThe chart levelsThe chart levels

Nivel #1

El primer nivel solamente incluirá un único nodo:

Level 1

HTML

Para describirlo usaremos una etiqueta h1, ya que es la parte más importante de nuestro gráfico:

1
<h1 class="level-1 rectangle">...</h1>

CSS

Usaremos su pseudoelemento ::before para crear una relación entre el primer y el segundo nivel:

1
/*CUSTOM VARIABLES HERE*/
2
3
.level-1 {
4
  background: var(--level-1);
5
}
6
7
.level-1::before {
8
  content: "";
9
  position: absolute;
10
  top: 50%;
11
  left: 100%;
12
  transform: translateY(-50%);
13
  width: 20px;
14
  height: 2px;
15
  background: var(--black);
16
}

Nivel #2

El segundo nivel estará compuesto por dos nodos:

Level 2

HTML

Para describirlo, usaremos una lista ordenada con dos elementos de lista. Cada elemento de lista contendrá un elemento h2:

1
<ol class="level-2-wrapper">
2
  <li>
3
    <h2 class="level-2 rectangle">...</h2>
4
  </li>
5
  <li>
6
    <h2 class="level-2 rectangle">...</h2>
7
  </li>
8
</ol>

CSS

Cada elemento de lista actuará como un contenedor de cuadrículas con dos columnas. Colocaremos el contenido de la primera en el borde superior del eje de la columna, mientras que el contenido de la última se encontrará en el borde inferior del eje de la columna.

También definiremos los pseudoelementos ::before y ::after de los elementos h2. Su trabajo será crear las relaciones entre los niveles adyacentes:

1
/*CUSTOM VARIABLES HERE*/
2
3
.level-2-wrapper {
4
  position: relative;
5
  padding-left: 20px;
6
  border-left: 2px solid var(--black);
7
}
8
9
.level-2-wrapper::before {
10
  display: none;
11
  content: "";
12
  position: absolute;
13
  top: -20px;
14
  left: 10px;
15
  width: 2px;
16
  height: calc(100% + 40px);
17
  background: var(--black);
18
}
19
20
.level-2-wrapper::after {
21
  display: none;
22
  content: "";
23
  position: absolute;
24
  left: 10px;
25
  bottom: -20px;
26
  width: calc(100% - 10px);
27
  height: 2px;
28
  background: var(--black);
29
}
30
31
.level-2-wrapper > li {
32
  position: relative;
33
  display: grid;
34
  align-items: flex-start;
35
  grid-column-gap: 20px;
36
  grid-template-columns: auto auto;
37
}
38
39
.level-2-wrapper > li:last-child {
40
  margin-top: 100px;
41
  align-items: flex-end;
42
}
43
44
.level-2 {
45
  background: var(--level-2);
46
}
47
48
.level-2::before {
49
  content: "";
50
  position: absolute;
51
  top: 50%;
52
  right: 100%;
53
  transform: translateY(-50%);
54
  width: 20px;
55
  height: 2px;
56
  background: var(--black);
57
}
58
59
.level-2::after {
60
  content: "";
61
  position: absolute;
62
  top: 50%;
63
  left: 100%;
64
  transform: translateY(-50%);
65
  width: 20px;
66
  height: 2px;
67
  background: var(--black);
68
}

Nivel #3

El tercer nivel incluirá cuatro nodos.

Asociaremos los dos primeros nodos con el primer nodo del segundo nivel, mientras que los dos últimos estarán asociados con su segundo nodo:

Level 3

HTML

Todavía en el interior de la lista inicial, en donde reside el segundo nivel, definiremos dos listas nuevas. Cada una de ellas contendrá dos elementos de lista. Para cada elemento especificaremos un elemento h3:

1
<ol class="level-2-wrapper">
2
  <li>
3
    ...
4
    <ol class="level-3-wrapper">
5
      <li>
6
        <h3 class="level-3 rectangle">...</h3>
7
      </li>
8
      <li>
9
        <h3 class="level-3 rectangle">...</h3>
10
      </li>
11
    </ol>
12
  </li>
13
  <li>
14
    ...
15
    <ol class="level-3-wrapper">
16
      <li>
17
        <h3 class="level-3 rectangle">...</h3>
18
      </li>
19
      <li>
20
        <h3 class="level-3 rectangle">...</h3>
21
      </li>
22
    </ol>
23
  </li>
24
</ol>

CSS

De manera similar al nivel anterior, vamos a considerar cada elemento de lista como un contenedor de cuadrículas y lo dividiremos en dos columnas.

De la misma forma, vamos a definir los pseudoelementos ::before y ::after de los elementos h2 para crear las conexiones necesarias:

1
/*CUSTOM VARIABLES HERE*/
2
3
.level-3-wrapper {
4
  position: relative;
5
  top: 34px;
6
  padding-left: 20px;
7
  border-left: 2px solid var(--black);
8
}
9
10
.level-3-wrapper::before {
11
  display: none;
12
  content: "";
13
  position: absolute;
14
  top: 0;
15
  left: 10px;
16
  width: 2px;
17
  height: 100%;
18
  background: var(--black);
19
}
20
21
.level-3-wrapper::after {
22
  display: none;
23
  content: "";
24
  position: absolute;
25
  left: 10px;
26
  bottom: 0px;
27
  width: calc(100% - 10px);
28
  height: 2px;
29
  background: var(--black);
30
}
31
32
.level-3-wrapper > li {
33
  display: grid;
34
  grid-column-gap: 20px;
35
  grid-template-columns: auto auto;
36
}
37
38
.level-3-wrapper > li:last-child {
39
  margin-top: 80px;
40
}
41
42
.level-2-wrapper > li:last-child .level-3-wrapper {
43
  top: -34px;
44
}
45
46
.level-3 {
47
  background: var(--level-3);
48
}
49
50
.level-3::before {
51
  content: "";
52
  position: absolute;
53
  top: 50%;
54
  right: 100%;
55
  transform: translateY(-50%);
56
  width: 20px;
57
  height: 2px;
58
  background: var(--black);
59
}
60
61
.level-3::after {
62
  content: "";
63
  position: absolute;
64
  top: 50%;
65
  left: 100%;
66
  transform: translateY(-50%);
67
  width: 20px;
68
  height: 2px;
69
  background: var(--black);
70
}

Nota: si tus nodos de texto se extienden a una línea separada, debes cambiar los siguientes valores codificados de forma fija: top: 34px y top: -34px.

Nivel #4

Para el cuarto nivel necesitaremos dieciséis nodos. Estos se distribuirán equitativamente en cuatro listas.

Cada nodo del tercer nivel incluirá una lista:

Level 4Level 4Level 4

HTML

Todavía en el interior de la lista inicial, en donde reside el segundo nivel, vamos a definir cuatro listas nuevas. Cada una de ellas contendrá cuatro elementos de lista. Para cada elemento de lista especificaremos un elemento h4:

1
<ol class="level-2-wrapper">
2
  <li>
3
    ...
4
    <ol class="level-3-wrapper">
5
      <li>
6
        ...
7
        <ol class="level-4-wrapper">
8
          <li>
9
            <h4 class="level-4 rectangle">...</h4>
10
          </li>
11
          ...
12
        </ol>
13
      </li>
14
      <li>
15
        ...
16
        <ol class="level-4-wrapper">
17
          <li>
18
            <h4 class="level-4 rectangle">...</h4>
19
          </li>
20
          ...
21
        </ol>
22
      </li>
23
    </ol>
24
  </li>
25
  <li>
26
    ...
27
    <ol class="level-3-wrapper">
28
      <li>
29
        ...
30
        <ol class="level-4-wrapper">
31
          <li>
32
            <h4 class="level-4 rectangle">...</h4>
33
          </li>
34
          ...
35
        </ol>
36
      </li>
37
      <li>
38
        ...
39
        <ol class="level-4-wrapper">
40
          <li>
41
            <h4 class="level-4 rectangle">...</h4>
42
          </li>
43
          ...
44
        </ol>
45
      </li>
46
    </ol>
47
  </li>
48
</ol>

CSS

Una vez más llevaremos a cabo las mismas acciones. En primer lugar, usaremos CSS Grid para crear el diseño de los nodos del cuarto nivel. Luego especificaremos los pseudoelementos necesarios de los elementos destino para establecer las conexiones:

1
/*CUSTOM VARIABLES HERE*/
2
3
.level-4-wrapper {
4
  position: relative;
5
  top: 34px;
6
  display: grid;
7
  grid-template-columns: repeat(4, 1fr);
8
  grid-column-gap: 20px;
9
  padding-left: 20px;
10
}
11
12
.level-4-wrapper::before {
13
  content: "";
14
  position: absolute;
15
  top: 0;
16
  left: 0;
17
  width: 2px;
18
  height: 50%;
19
  background: var(--black);
20
}
21
22
.level-3-wrapper > li:last-child .level-4-wrapper {
23
  top: -34px;
24
}
25
26
.level-3-wrapper > li:last-child .level-4-wrapper::before {
27
  top: auto;
28
  bottom: 0;
29
}
30
31
.level-4 {
32
  background: var(--level-4);
33
}
34
35
.level-4::before {
36
  content: "";
37
  position: absolute;
38
  top: 50%;
39
  right: 100%;
40
  transform: translateY(-50%);
41
  width: 20px;
42
  height: 2px;
43
  background: var(--black);
44
}

Nota: si tus nodos de texto se extienden a una línea separada, debes cambiar los valores top: 34px y top: -34px, que están codificados de forma fija.

4. Agrega responsividad

Como ya has adivinado, para nuestros estilos hemos seguido un enfoque de escritorio. En términos generales, yo prefiero construir teniendo en cuenta las pantallas grandes en primer lugar, y luego paso a las pantallas más pequeñas y menos complicadas.

En las pantallas de entre 1301px y 1650px, el gráfico seguirá mostrándose en modo horizontal, pero sus nodos tendrán un ancho menor (200px en lugar de 150px).

En pantallas de hasta 1300px de ancho, todos los nodos del gráfico se mostrarán de manera vertical, de esta forma:

Responsive Layout of Horizontal Organization ChartResponsive Layout of Horizontal Organization ChartResponsive Layout of Horizontal Organization Chart

A diferencia del diseño horizontal, aquí el ancho y la tipografía de los nodos de texto difieren dependiendo de sus niveles. Mientras más alto sea el nivel, más anchos serán los nodos y más grande será la tipografía.

Por supuesto, no dudes en cambiar estos puntos de interrupción dependiendo de tu contenido.

Vale la pena señalar que este diseño es ligeramente diferente en comparación con el diseño responsivo del gráfico vertical:

Responsive Layout of Organization ChartResponsive Layout of Organization ChartResponsive Layout of Organization Chart

En caso de que te lo preguntes, no hay un propósito específico detrás de esta nueva implementación. Solamente quería mostrarte dos diseños responsivos diferentes. No dudes en utilizar cualquiera de estos en tus páginas.

Estos son los estilos responsivos:

1
@media screen and (max-width: 1650px) {
2
  .rectangle {
3
    width: 150px;
4
  }
5
}
6
7
@media screen and (max-width: 1300px) {
8
  body {
9
    font-size: 16px;
10
  }
11
  
12
  h1,
13
  h2,
14
  h3,
15
  h4 {
16
    font-size: revert;
17
  }
18
19
  .rectangle {
20
    padding: 20px 10px;
21
    width: auto;
22
  }
23
24
  .container {
25
    display: block;
26
  }
27
28
  .level-1 {
29
    margin-bottom: 20px;
30
  }
31
32
  .level-1::before,
33
  .level-2::after,
34
  .level-3::after {
35
    display: none;
36
  }
37
38
  .level-2-wrapper::before,
39
  .level-2-wrapper::after,
40
  .level-3-wrapper::before,
41
  .level-3-wrapper::after,
42
  .level-2-wrapper > li,
43
  .level-3-wrapper > li {
44
    display: block;
45
  }
46
47
  .level-2-wrapper {
48
    padding-left: 30px;
49
    border-left: none;
50
  }
51
52
  .level-2-wrapper > li:last-child {
53
    margin-top: 50px;
54
  }
55
56
  .level-2-wrapper > li:last-child .level-3-wrapper,
57
  .level-3-wrapper > li:last-child .level-4-wrapper,
58
  .level-3-wrapper,
59
  .level-4-wrapper {
60
    top: 0;
61
  }
62
63
  .level-3-wrapper {
64
    padding: 20px 0 20px 30px;
65
    border-left: none;
66
  }
67
68
  .level-3-wrapper > li:last-child {
69
    margin-top: 50px;
70
  }
71
72
  .level-4-wrapper {
73
    padding: 20px 0 0 30px;
74
    grid-template-columns: repeat(2, 1fr);
75
  }
76
77
  .level-4-wrapper > li:first-child {
78
    margin-bottom: 20px;
79
  }
80
81
  .level-4-wrapper::before {
82
    left: 10px;
83
    height: 100%;
84
  }
85
}

La palabra clave revert

De los estilos anteriores, presta especial atención a la nueva palabra clave revert de CSS que aplicamos a los encabezados. Eso nos ayudará a restaurar sus estilos de navegador predeterminados. Afortunadamente, su compatibilidad con los navegadores crece día a día.

Conclusión

¡Eso es todo por hoy, amigos! En este punto, ya cuentas con todo lo que necesitas para crear tus propios organigramas usando solamente CSS.

Por supuesto, en un escenario real quizá prefieras usar una potente biblioteca de JavaScript, como Highcharts.js, para crear un gráfico de este tipo. Sin embargo, extender los límites de CSS sin ignorar sus limitaciones siempre es una excelente manera de aprender y expandir tus conocimientos. Además, con la combinación de herramientas y funciones como CSS Grid y pseudoelementos, puedes lograr cosas verdaderamente interesantes.

Recordemos lo que hemos creado:

Sigue adelante, bifurca la demostración y ponte manos a la obra. No tengas miedo de destruirla y experimentar con ella. Puedes lograr diferentes variaciones sin poner demasiado esfuerzo. Por ejemplo, esta es otra alternativa rápida para las pantallas de escritorio:

Another implementation for the horizontal organizational chartAnother implementation for the horizontal organizational chartAnother implementation for the horizontal organizational chart

Por último, pero no por eso menos importante, aquí en Tuts+ existen muchos tutoriales detallados que muestran cómo implementar diferentes tipos de gráficos en CSS (en algunas ocasiones con JavaScript). Asegúrate de echarles un vistazo y, como siempre, ¡muchas gracias por leer!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.