Gráficos en CSS: cómo crear un organigrama
Spanish (Español) translation by Ana Paulina Figueroa (you can also view the original English article)
En tutoriales anteriores hemos aprendido cómo crear diferentes tipos de gráficos, incluyendo gráficos de barras, gráficos de termómetro y gráficos de anillo. Hoy continuaremos este camino construyendo un organigrama puramente en CSS.
¿Estás listo para poner a prueba tus habilidades en CSS?
El organigrama que vamos a construir
Este es el gráfico en CSS que vamos a crear:
Está compuesto por cuatro niveles y describe la estructura jerárquica de una empresa.
¿Qué es un organigrama?
Para averiguar qué es un organigrama, tomemos prestada la definición de Wikipedia:
"Un diagrama organizativo, también llamado organigrama o tabla organizacional, es un diagrama que muestra la estructura de una organización y las relaciones y rangos relativos de sus partes y puestos/trabajos. El término también se usa para diagramas similares, por ejemplo aquellos que muestran los diferentes elementos de un campo del conocimiento o de un grupo de lenguajes."
Aquí puedes ver un ejemplo:



Este tipo de gráfico se usa comúnmente para presentar las relaciones entre las personas o los departamentos de una empresa. En un sitio web corporativo, probablemente lo encontrarás en la página "Acerca de nosotros" o "Empresa".
También verás organigramas usados para representar árboles genealógicos (consulta el árbol genealógico de la familia real británica y la línea de sucesión en el sitio web de la BBC). Son ideales para ilustrar jerarquías.
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 ir por sus niveles, configuraremos algunas reglas de restablecimiento y clases de ayuda:
1 |
:root { |
2 |
--level-1: #8dccad; |
3 |
--level-2: #f5cc7f; |
4 |
--level-3: #7b9fe0; |
5 |
--level-4: #f27c8d; |
6 |
--black: black; |
7 |
}
|
8 |
* { |
9 |
padding: 0; |
10 |
margin: 0; |
11 |
box-sizing: border-box; |
12 |
}
|
13 |
ol { |
14 |
list-style: none; |
15 |
}
|
16 |
body { |
17 |
margin: 50px 0 100px; |
18 |
text-align: center; |
19 |
font-family: "Inter", sans-serif; |
20 |
}
|
21 |
.container { |
22 |
max-width: 1000px; |
23 |
padding: 0 10px; |
24 |
margin: 0 auto; |
25 |
}
|
26 |
.rectangle { |
27 |
position: relative; |
28 |
padding: 20px; |
29 |
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.15); |
30 |
}
|
Presta atención a la clase rectangle. La agregaremos a cada nodo/elemento de nuestro gráfico.
Nota: no optimicé el CSS por simplicidad. Esto te ayudará a comprender mejor los estilos de cada nivel.
3. Especifica los niveles
En este punto estamos listos para especificar los niveles del gráfico; como discutimos anteriormente, aquí tendremos cuatro de ellos:



Cada nivel representará un rol en una empresa, comenzando por el de mayor rango.
Nivel #1
El primer nivel incluirá solamente un nodo:



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 nivel y el segundo:
1 |
/*CUSTOM VARIABLES HERE*/
|
2 |
.level-1 { |
3 |
width: 50%; |
4 |
margin: 0 auto 40px; |
5 |
background: var(--level-1); |
6 |
}
|
7 |
.level-1::before { |
8 |
content: ""; |
9 |
position: absolute; |
10 |
top: 100%; |
11 |
left: 50%; |
12 |
transform: translateX(-50%); |
13 |
width: 2px; |
14 |
height: 20px; |
15 |
background: var(--black); |
16 |
}
|
Nivel #2
El segundo nivel estará compuesto por dos nodos:



Como veremos en un momento, cada nodo incluirá otros nodos hijos.
Estos nodos hijos representarán niveles inferiores de la jerarquía administrativa.
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
Crearemos el diseño de este nivel gracias a la ayuda de CSS Grid.
A continuación usaremos el pseudoelemento ::before de elementos específicos para crear las asociaciones entre los nodos de este nivel y los niveles adyacentes:
1 |
/*CUSTOM VARIABLES HERE*/
|
2 |
.level-2-wrapper { |
3 |
position: relative; |
4 |
display: grid; |
5 |
grid-template-columns: repeat(2, 1fr); |
6 |
}
|
7 |
.level-2-wrapper::before { |
8 |
content: ""; |
9 |
position: absolute; |
10 |
top: -20px; |
11 |
left: 25%; |
12 |
width: 50%; |
13 |
height: 2px; |
14 |
background: var(--black); |
15 |
}
|
16 |
.level-2-wrapper::after { |
17 |
display: none; |
18 |
content: ""; |
19 |
position: absolute; |
20 |
left: -20px; |
21 |
bottom: -20px; |
22 |
width: 100%; |
23 |
height: 2px; |
24 |
background: var(--black); |
25 |
}
|
26 |
.level-2-wrapper li { |
27 |
position: relative; |
28 |
}
|
29 |
.level-2-wrapper > li::before { |
30 |
content: ""; |
31 |
position: absolute; |
32 |
bottom: 100%; |
33 |
left: 50%; |
34 |
transform: translateX(-50%); |
35 |
width: 2px; |
36 |
height: 20px; |
37 |
background: var(--black); |
38 |
}
|
39 |
.level-2 { |
40 |
width: 70%; |
41 |
margin: 0 auto 40px; |
42 |
background: var(--level-2); |
43 |
}
|
44 |
.level-2::before { |
45 |
content: ""; |
46 |
position: absolute; |
47 |
top: 100%; |
48 |
left: 50%; |
49 |
transform: translateX(-50%); |
50 |
width: 2px; |
51 |
height: 20px; |
52 |
background: var(--black); |
53 |
}
|
54 |
.level-2::after { |
55 |
display: none; |
56 |
content: ""; |
57 |
position: absolute; |
58 |
top: 50%; |
59 |
left: 0%; |
60 |
transform: translate(-100%, -50%); |
61 |
width: 20px; |
62 |
height: 2px; |
63 |
background: var(--black); |
64 |
}
|
Observa que también definimos el pseudoelemento ::after de los nodos de segundo nivel. Esto aparecerá solamente en las pantallas pequeñas.
Nivel #3
El tercer nivel incluirá cuatro nodos.
Asociaremos los primeros dos nodos con el primer nodo del segundo nivel, y asociaremos los dos últimos nodos con su segundo nodo:



HTML
Definiremos dos listas nuevas todavía dentro de la lista inicial en donde reside el segundo nivel. Cada una de ellas contendrá dos elementos de lista. Para cada elemento de lista 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
Posicionaremos los nodos nuevamente gracias a la ayuda de CSS Grid.
De la misma forma, estableceremos el pseudoelemento ::before de elementos específicos para crear las conexiones necesarias:
1 |
/*CUSTOM VARIABLES HERE*/
|
2 |
.level-3-wrapper { |
3 |
position: relative; |
4 |
display: grid; |
5 |
grid-template-columns: repeat(2, 1fr); |
6 |
grid-column-gap: 20px; |
7 |
width: 90%; |
8 |
margin: 0 auto; |
9 |
}
|
10 |
.level-3-wrapper::before { |
11 |
content: ""; |
12 |
position: absolute; |
13 |
top: -20px; |
14 |
left: calc(25% - 5px); |
15 |
width: calc(50% + 10px); |
16 |
height: 2px; |
17 |
background: var(--black); |
18 |
}
|
19 |
.level-3-wrapper > li::before { |
20 |
content: ""; |
21 |
position: absolute; |
22 |
top: 0; |
23 |
left: 50%; |
24 |
transform: translate(-50%, -100%); |
25 |
width: 2px; |
26 |
height: 20px; |
27 |
background: var(--black); |
28 |
}
|
29 |
.level-3 { |
30 |
margin-bottom: 20px; |
31 |
background: var(--level-3); |
32 |
}
|
Nivel #4
Para el cuarto nivel necesitaremos dieciséis nodos. Estos serán distribuidos igualmente en cuatro listas.
Cada nodo del tercer nivel incluirá una lista:



HTML
Definiremos cuatro listas nuevas todavía en el interior de la lista inicial en la que reside el segundo nivel. 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
Nuevamente estableceremos el pseudoelemento ::before de elementos específicos para asociar los nodos del cuarto nivel con sus padres:
1 |
/*CUSTOM VARIABLES HERE*/
|
2 |
.level-4-wrapper { |
3 |
position: relative; |
4 |
width: 80%; |
5 |
margin-left: auto; |
6 |
}
|
7 |
.level-4-wrapper::before { |
8 |
content: ""; |
9 |
position: absolute; |
10 |
top: -20px; |
11 |
left: -20px; |
12 |
width: 2px; |
13 |
height: calc(100% + 20px); |
14 |
background: var(--black); |
15 |
}
|
16 |
.level-4-wrapper li + li { |
17 |
margin-top: 20px; |
18 |
}
|
19 |
.level-4 { |
20 |
font-weight: normal; |
21 |
background: var(--level-4); |
22 |
}
|
23 |
.level-4::before { |
24 |
content: ""; |
25 |
position: absolute; |
26 |
top: 50%; |
27 |
left: 0%; |
28 |
transform: translate(-100%, -50%); |
29 |
width: 20px; |
30 |
height: 2px; |
31 |
background: var(--black); |
32 |
}
|
Los organigramas y la responsividad
Lograr que un organigrama sea responsivo es complicado. Recuerdo tener que reconstruir el marcado una o dos veces hasta llegar a esta versión. Por lo tanto, si planeas crear un gráfico de ese tipo, te recomiendo que sigas un enfoque basado en los dispositivos móviles.
Con todo esto en mente, este es su diseño para dispositivos móviles:



Para lograr este comportamiento tenemos que modificar algunos estilos:
1 |
@media screen and (max-width: 700px) { |
2 |
.rectangle { |
3 |
padding: 20px 10px; |
4 |
}
|
5 |
.level-1, |
6 |
.level-2 { |
7 |
width: 100%; |
8 |
}
|
9 |
.level-1 { |
10 |
margin-bottom: 20px; |
11 |
}
|
12 |
.level-1::before, |
13 |
.level-2-wrapper > li::before { |
14 |
display: none; |
15 |
}
|
16 |
.level-2-wrapper, |
17 |
.level-2-wrapper::after, |
18 |
.level-2::after { |
19 |
display: block; |
20 |
}
|
21 |
.level-2-wrapper { |
22 |
width: 90%; |
23 |
margin-left: 10%; |
24 |
}
|
25 |
.level-2-wrapper::before { |
26 |
left: -20px; |
27 |
width: 2px; |
28 |
height: calc(100% + 40px); |
29 |
}
|
30 |
.level-2-wrapper > li:not(:first-child) { |
31 |
margin-top: 50px; |
32 |
}
|
33 |
}
|
¡Hemos terminado nuestro gráfico en CSS!
¡Enhorabuena, amigos! Sin escribir una sola línea de JavaScript, hemos logrado construir un organigrama completamente funcional.
Recordemos lo que construimos:
Por supuesto, ten en cuenta que nuestro gráfico tiene una estructura específica. Dependiendo de tus necesidades es posible que quieras enriquecer su contenido o modificar su diseño. Si necesitas algo más avanzado o dinámico, echa un vistazo a algunas bibliotecas de JavaScript como Highcharts.js.
¿Alguna vez has creado un gráfico en CSS? Si es así, ¡por favor comparte tu experiencia con nosotros!
Más gráficos en CSS (algunas veces con JavaScript)
Si aún necesitas un poco de inspiración, no olvides consultar mis otros gráficos en el archivo de Tuts+ o haz una búsqueda rápida en CodePen.
Como siempre, ¡muchas gracias por leer!


CSSCómo construir un gráfico de anillo semicircular con CSSGeorge Martsoukos

CSSCómo construir una página de portafolio estática con CSS y JavaScriptGeorge Martsoukos

CSSConstruye un portafolio estático con un gráfico de barras avanzado en CSSGeorge Martsoukos

CSSCómo construir un gráfico de termómetro animado en CSSGeorge Martsoukos

Gráficos en CSSCómo construir un diagrama de Gantt simple con CSS y JavaScriptGeorge Martsoukos



