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

Cómo crear un componente de acordeón con el truco Checkbox de CSS

Scroll to top

Spanish (Español) translation by Carlos (you can also view the original English article)

Final product imageFinal product imageFinal product image
What You'll Be Creating

En este breve tutorial, aprenderemos a crear un componente de acordeón flexible usando solo CSS y aprovechando «la técnica con el truco checkbox de CSS». Y quizá lo más importante, nuestro componente será completamente responsivo y su diseño cambiará entre horizontal y vertical según el tamaño de la ventana gráfica.

Durante el proceso, discutiremos cómo funciona el truco checkbox de CSS, y veremos esta técnica siendo utilizada por otros desarrolladores en CodePen para inspirarnos. ¿Suena interesante?

Nuestro acordeón responsivo con CSS

Esto es lo que crearemos durante este tutorial:

Please accept marketing cookies to load this content.

Nota: Este tutorial asume que tienes cierto conocimiento de flexbox. Si estás empezando, revisa este tutorial de flexbox para principiantes:

Espera, ¿cuál es el truco checkbox de CSS?

El truco checkbox de CSS te permite controlar ciertos estilos dependiendo si las casillas de verificación (o botones de radio) están marcadas o no. Usa el selector de pseudoclases :checked, que nos permite indicar «si una casilla de verificación (checkbox ) está marcada, aplicar estas reglas de estilo a su elemento hermano, etc.».

Los desarrolladores suelen ocultar la entrada en sí, controlando el valor marcado a mediante su etiqueta, de modo que los usuarios ni siquiera se enteran de que están activando una casilla de verificación.

Es una de mis favoritas; de hecho, he utilizado la misma técnica en varios tutoriales:

1. Empieza con el marcado en HTML

Para los fines de este ejercicio, tomaremos contenido de Wikipedia sobre: animales, plantas, espacio y ríos.

Luego, crearemos los botones de opción correspondientes que agruparemos bajo la palabra clave wiki:

1
<input type="radio" id="animal" name="wiki" value="Animal" checked>
2
<input type="radio" id="plant" name="wiki" value="Plant">
3
<input type="radio" id="space" name="wiki" value="Space">
4
<input type="radio" id="river" name="wiki" value="River">

Crea una lista sin ordenar

A continuación, definiremos una lista no ordenada con cuatro elementos. Cada objeto de la lista representará un elemento del acordeón/panel y contendrá dos elementos:

  1. En primer lugar, una etiqueta que servirá como título del acordeón y se encargará de abrir el elemento objetivo. Su valor for deberá coincidir con el valor id de uno de los botones de radio mencionados.
  2. En segundo lugar, un elemento div que servirá como el área de contenido del acordeón.

De forma predeterminada un panel en nuestro acordeón debe estar abierto. Tomando eso en consideración, añadamos el atributo checked al primer botón de opción.

Teniendo todo junto, aquí está el marcado que necesitaremos:

1
<ul class="accordion">
2
  <li>
3
    <label for="animal" class="accordion-title">
4
      <span>...</span>
5
      <span class="accordion-heading">...</span>
6
    </label>
7
    <div class="accordion-content">...</div>
8
  </li>
9
  <li>
10
    <label for="plant" class="accordion-title">
11
      <span>...</span>
12
      <span class="accordion-heading">...</span>
13
    </label>
14
    <div class="accordion-content">...</div>
15
  </li>
16
  <li>
17
    <label for="space" class="accordion-title">
18
      <span>...</span>
19
      <span class="accordion-heading">...</span>
20
    </label>
21
    <div class="accordion-content">...</div>
22
  </li>
23
  <li>
24
    <label for="river" class="accordion-title">
25
      <span>...</span>
26
      <span class="accordion-heading">...</span>
27
    </label>
28
    <div class="accordion-content">...</div>
29
  </li>
30
</ul>

2. Define los estilos

Con el marcado listo (y en línea con el truco checkbox de CSS que describí anteriormente) primero ocultaremos visualmente los botones de opción moviéndolos fuera de la pantalla:

1
input[type="radio"] {
2
  position: absolute;
3
  left: -9999px;
4
}

El acordeón tendrá un ancho máximo, una altura mínima y se comportará como un contenedor flexible:

1
/*CUSTOM VARIABLES HERE*/
2
3
.accordion {
4
  display: flex;
5
  width: calc(100% - 20px);
6
  max-width: 800px;
7
  min-height: 380px;
8
  margin: 0 auto;
9
  background: var(--accordion-color);
10
  color: var(--white);
11
}

Además, cada elemento de la lista servirá como una envoltura flexible:

1
.accordion li {
2
  display: flex;
3
}

Los elementos del acordeón deben estar separados, así que vamos a darles un borde:

1
/*CUSTOM VARIABLES HERE*/
2
3
.accordion li:not(:last-child) {
4
  border: 1px solid var(--separator-color);
5
}

Cada título (etiqueta) dentro de un objeto será un contenedor flexible y sus elementos secundarios se distribuirán de forma vertical a través del eje principal. Además, todos los elementos tendrán un ancho de 70 px:

1
/*CUSTOM VARIABLES HERE*/
2
3
.accordion .accordion-title {
4
  display: flex;
5
  flex-direction: column;
6
  justify-content: space-between;
7
  width: 70px;
8
  font-size: 1.4rem;
9
  font-weight: bold;
10
  line-height: normal;
11
  padding: 20px 10px;
12
  background: var(--title-color);
13
  transition: color 0.1s;
14
}
15
16
.accordion .accordion-title:hover {
17
  color: var(--active-color);
18
}

El texto dentro de .accordion-heading se rotará verticalmente:

1
.accordion .accordion-heading {
2
  display: inline-block;
3
  white-space: nowrap;
4
  transform-origin: bottom;
5
  transform: rotate(-90deg) translate(50%, 50%);
6
}

Inicialmente, aparte del primer panel, todos los demás paneles estarán ocultos:

1
.accordion .accordion-content {  
2
  display: none;
3
  align-items: center;
4
  padding: 20px;
5
}

3. El truco de checkbox: Alternar los paneles

Ahora para crear la magia. Cada vez que hagamos clic en una etiqueta, deberá aparecer su contenido asociado. Para hacer que esto suceda, aprovecharemos la pseudoclase :checked, el selector sibling subsecuente (~) y el combinador sibling adyacente (+). Si necesitas un repaso de lo que hacen estos selectores, revisa este tutorial:

Así que,cuando un elemento se vuelve visible, recibirá display: flex y no display: block. Esto se debe a que queremos centrar verticalmente su contenido aprovechando el valor de propiedad align-items: center. Asimismo, los colores del panel activo tienen que cambiar, de tal modo que un visitante pueda comprender claramente qué panel está abierto.

De forma opcional, cada vez que un botón de opción recibe focus, podemos añadir una descripción a su etiqueta asociada. Este pequeño detalle nos ayudará a mejorar la accesibilidad de nuestro componente.

Aquí están todo lo relacionado con CSS:

1
/*CUSTOM VARIABLES HERE*/
2
3
[value="Animal"]:checked ~ .accordion [for="animal"] + .accordion-content,
4
[value="Plant"]:checked ~ .accordion [for="plant"] + .accordion-content,
5
[value="Space"]:checked ~ .accordion [for="space"] + .accordion-content,
6
[value="River"]:checked ~ .accordion [for="river"] + .accordion-content {
7
  display: flex;
8
}
9
10
[value="Animal"]:checked ~ .accordion [for="animal"],
11
[value="Plant"]:checked ~ .accordion [for="plant"],
12
[value="Space"]:checked ~ .accordion [for="space"],
13
[value="River"]:checked ~ .accordion [for="river"] {
14
  color: var(--active-color);
15
}
16
17
/*optional*/
18
[value="Animal"]:focus ~ .accordion [for="animal"],
19
[value="Plant"]:focus ~ .accordion [for="plant"],
20
[value="Space"]:focus ~ .accordion [for="space"],
21
[value="River"]:focus ~ .accordion [for="river"] {
22
  outline: 1px solid var(--active-color);
23
}

4. Volviéndolo responsivo

Como lo comentamos, en pantallas pequeñas los elementos dentro del acordeón deben apilarse, por lo que el acordeón tendrá un diseño vertical. Gracias a flexbox, podemos implementar este diseño sin tanto esfuerzo. De hecho, todo lo que tenemos que hacer es actualizar la dirección de las envolturas flexibles y restablecer el valor de la propiedad transform de .accordion-heading.

Veamos los estilos responsivos dentro de un «media query»:

1
@media screen and (max-width: 650px) {
2
  .accordion {
3
    min-height: 0;  
4
  }
5
  
6
  .accordion,
7
  .accordion li {
8
    flex-direction: column;
9
  }
10
  
11
  .accordion .accordion-title {
12
    flex-direction: row;
13
    width: auto;
14
  }
15
  
16
  .accordion .accordion-heading {
17
    transform: none;
18
  }
19
  
20
  .accordion .accordion-title,
21
  .accordion .accordion-content {
22
    padding: 20px;
23
  }
24
}

5. Bono: contenido limitado

En nuestro caso, existe mucho contenido dentro de cada uno de los elementos del acordeón, por lo que todo se ve muy bien. Pero, asegurémonos de que el acordeón seguirá funcionando bien cuando no haya suficiente contenido dentro de los paneles (por ejemplo, un panel que contenga solo enlaces sociales).

The accordion with limited contentThe accordion with limited contentThe accordion with limited content

Para satisfacer este escenario, tenemos que hacer dos cosas:

  • Añadir flex-grow: 1 al elemento de la lista que contenga el panel activo. Para dirigirnos solo a ese elemento y no a todos, necesitaremos agregar un nuevo atributo personalizado (data-radio) a los elementos de la lista con el valor del valor de su etiqueta.
  • Agregarflex-grow: 1 a .accordion-content, para que se expanda y cubra todo el ancho principal.
  • Centrar horizontalmente el contenido de .accordion-content gracias a justify-content: center

Teniendo en cuenta todo lo anterior, modificaremos nuestro HTML de la siguiente manera:

1
<ul class="accordion">
2
  <li data-radio="animal">...</li>
3
  <li data-radio="plant">...</li>
4
  <li data-radio="space">...</li>
5
  <li data-radio="river">...</li>
6
</ul>

Luego, en el CSS incluiremos estos estilos:

1
.accordion .accordion-content {
2
  justify-content: center;
3
  flex-grow: 1;
4
}
5
6
[value="Animal"]:checked ~ .accordion [data-radio="animal"],
7
[value="Plant"]:checked ~ .accordion [data-radio="plant"],
8
[value="Space"]:checked ~ .accordion [data-radio="space"],
9
[value="River"]:checked ~ .accordion [data-radio="river"] {
10
  flex-grow: 1;
11
}

Conclusión

¡Eso es todo amigos! En este breve tutorial, logramos crear un acordeón usando solo CSS y aprovechando el «truco checkbox de CSS». Esperemos que hayas disfrutado de este ejercicio y que lo amplíes para tus propósitos específicos.

Aquí tienes un recordatorio de lo que hemos creado:

Please accept marketing cookies to load this content.

Proyecto extra

Para concluir, solo ten presente que con esta implementación únicamente se puede abrir un panel del acordeón a la vez. Eso es porque utilizamos botonesde radio en el marcado. En caso de que quieras mostrar varios elementos de acordeón al mismo tiempo, reemplaza los botones de opción con casillas de verificación y haz los cambios necesarios (oculta las casillas de verificación) en el CSS.

Y como siempre, ¡muchas gracias por leer!

Más inspiración con el truco de checkbox en CodePen

¿Qué mejor lugar para ver lo que otros han creado con el truco chekbox de CSS que CodePen? Aquí tienes algunos excelentes ejemplos para abrir el apetito:

Toggles responsivos con emojis por George W. Park

Please accept marketing cookies to load this content.

Contenido con pestañas con solo CSS por Stephen Greig

Please accept marketing cookies to load this content.

Modal con puro CSS - «El truco de checkbox» por BeardedBear

Please accept marketing cookies to load this content.

Navegación con el truco checkbox de CSS por JAD3

Please accept marketing cookies to load this content.

Lecturas adicionales

Revisa estos recursos para aprender más sobre técnicas CSS similares y otras maneras de crear componentes de acordeón (¿alguien dijo Bootstrap?):