Artículo original escrito por: Kingsley Ubah
Artículo original: How to Build an Accordion Menu Using HTML, CSS and JavaScript
Traducido y adaptado por: Ignacio Collantes

Puedes utilizar HTML, CSS y JavaScript para crear elementos web elegantes y dinámicos. Y un elemento útil que puedes construir es un menú acordeón.

Los menús en acordeón se expanden y contraen cuando el usuario hace clic en un botón. Es una gran manera de no tener que mostrar toda la información sobre un tema al principio, y en su lugar dar a los usuarios la opción de mostrar solo lo que necesitan.

En este tutorial, les mostraré cómo construir un menú acordeón simple que se parece a esto:

Peek-2022-02-26-14-27-1

¿Qué es un menú acordeón?

En el diseño de la interfaz de usuario, un menú acordeón es una lista apilada verticalmente de varias piezas de información. Para cada lista, hay una cabecera etiquetada que apunta al contenido correspondiente. El contenido de cada lista está oculto por defecto. Al hacer clic en una etiqueta concreta, se despliega su contenido.

Un caso de uso muy común para los acordeones es el de contener una lista de preguntas frecuentes. Al hacer clic en una pregunta, se mostrará la respuesta correspondiente.

Cómo construir un menú acordeón usando HTML, CSS y JS

Comenzaremos por definir el marcado HTML. Si estás usando un IDE como VS Code y tienes emmet instalado, crea un nuevo archivo index.html y escribe ! seguido de enter. Esto debería crear el código HTML para tu proyecto.

Alternativamente, puedes copiar el siguiente código en tu index.html, u obtener el código para este proyecto desde Codepen.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Documento</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>

  <script src="app.js" type="text/javascript"></script>
</body>
</html>
Estructura de la página HTML

La estructura de la carpeta es sencilla. Crearemos una carpeta llamada acordeón. Dentro de la carpeta crearemos tres archivos: index.html, styles.css, y app.js. También enlazaremos todos los archivos en nuestro marcado HTML como puedes ver arriba.

Marcado HTML para el Acordeón

Para cada lista del menú, tendremos dos div: uno para la etiqueta y otro para el contenido.

<body>
  <div class="acordeon-cuerpo">
  <div class="acordeon">
    <h1>Preguntas Frecuentes</h1>
    <hr>
    <div class="contenedor">
      <div class="label">¿Qué es HTML?</div>
      <div class="content">El lenguaje de marcas de hipertexto (HTML) es un lenguaje informático que compone la mayoría de las páginas web y aplicaciones en línea. Un hipertexto es un texto que se utiliza para hacer referencia a otros fragmentos de texto, mientras que un lenguaje de marcas es una serie de marcas que indican a los servidores web el estilo y la estructura de un documento. El lenguaje HTML es muy sencillo de aprender y utilizar.</div>
    </div>
    <hr>
    <div class="contenedor">
      <div class="label">¿Qué es CSS?</div>
      <div class="content">CSS son las siglas de Cascading Style Sheets (hojas de estilo en cascada). Es el lenguaje para describir la presentación de las páginas web, incluyendo los colores, el diseño y las fuentes, haciendo así que nuestras páginas web sean presentables para los usuarios. CSS está diseñado para hacer hojas de estilo para la web. Es independiente de HTML y puede utilizarse con cualquier lenguaje de marcado basado en XML. El CSS es popularmente llamado el lenguaje de diseño de la web.
</div>
    </div>
    <hr>
    <div class="contenedor">
      <div class="label">¿Qué es JavaScript?</div>
      <div class="content">JavaScript es un lenguaje de programación que permite implementar funciones complejas en las páginas web. Cada vez que una página web hace algo más que limitarse a mostrar información estática para que la veas, mostrando actualizaciones puntuales de contenido, mapas interactivos, gráficos 2D/3D animados, videocámaras con desplazamiento, etc., puedes apostar que JavaScript está probablemente involucrado. Es el tercero del trío web.
</div>
    </div>
    <hr>
    <div class="container">
      <div class="label">¿Qué es React?</div>
      <div class="content">React es una biblioteca de JavaScript creada para construir interfaces de usuario rápidas e interactivas para aplicaciones web y móviles. Es una biblioteca de código abierto, basada en componentes, responsable únicamente de la capa de vista de la aplicación. En la arquitectura Modelo-Vista-Controlador (MVC), la capa de vista es responsable del aspecto y la sensación de la aplicación. React fue creado por Jordan Walke, un ingeniero de software de Facebook. </div>
    </div>
    <hr>
    <div class="container">
      <div class="etiqueta">¿Qué es PHP?</div>
      <div class="contenido">PHP es un lenguaje de scripting del lado del servidor y de propósito general que es especialmente adecuado para el desarrollo web. Originalmente, PHP significaba "Personal Home Page". Sin embargo, ahora significa Hypertext Preprocessor. Es un acrónimo recursivo porque la primera palabra también es un acrónimo.</div>
    </div>
    <hr>
    <div class="contenedor">
      <div class="etiqueta">¿Qué es Node JS?</div>
      <div class="contenido">Node.js es un entorno de ejecución de JavaScript de código abierto y multiplataforma que se ejecuta en el motor V8 y ejecuta código JavaScript fuera de un navegador web. Node.js permite a los desarrolladores utilizar JavaScript para escribir herramientas de línea de comandos y para la ejecución de scripts del lado del servidor para producir contenidos dinámicos de páginas web antes de que la página se envíe al navegador web del usuario. Por lo tanto, Node.js representa un paradigma de "JavaScript en todas partes".</div>
    </div>
    <hr>
  </div>
  </div>

  <script src="app.js" type="text/javascript"></script>
</body>
Markup for Accordion Menu

Sin CSS, nuestra página se verá toda desnuda, así:

image-33
Cómo se ve el menú acordeón sin CSS

Cómo estilizar el acordeón con CSS

Queremos que nuestro menú acordeón se vea bien, por supuesto. Es hora de poner en juego algo de CSS. He añadido algunos comentarios en el código para explicar lo que hace cada pieza:

@import url('https://fonts.googleapis.com/css2?family=Rubik:wght@300&display=swap');

/* Establece el color de fondo del cuerpo en azul. Establece el tipo de letra a Rubik */

body {
  background-color: #0A2344;
  font-family: 'rubik', sans-serif;
}

/* Alinea el texto del encabezado al centro. */
 
h1 {
  text-align: center;
}

/* Establece el ancho del acordeón. Establece el margen a 90px en la parte superior e inferior y auto a la izquierda y derecha */

.acordeon {
  width: 800px;
  margin: 90px auto;
  color: black;
  background-color: white;
  padding: 45px 45px;
}

Con todos estos estilos aplicados, este es el aspecto que tendrá ahora nuestro acordeón:

image-34
Estilos añadidos al menú acordeón

Ahora tenemos que empezar a trabajar en el interior para configurar su funcionalidad. En primer lugar, establecemos la propiedad position de cada uno de los contenedores (que contienen tanto la etiqueta como el contenido) como relativa.

Esto significa que ahora podemos posicionar sus hijos en relación con él.

.acordeon .contenedor {
  position: relative;
  margin: 10px 10px;
}

/* Posiciona las etiquetas en relación con el contenedor. Añade relleno en la parte superior e inferior y aumenta el tamaño de la fuente. También hace que su cursor sea un puntero */

.acordeon .etiqueta {
  position: relative;
  padding: 10px 0;
  font-size: 30px;
  color: black;
  cursor: pointer;
}

Ahora puedes notar la diferencia en la imagen de abajo:

image-35

La siguiente acción será añadir un pequeño signo "+" al final de cada lista. Esto permitirá a los usuarios saber que pueden ampliar la sección para aprender/ver más.

Para ello, utilizaremos el selector ::before. El selector ::before y ::after se utiliza para colocar el contenido antes o después de un elemento especificado.

Aquí, estamos insertando '+' antes de la etiqueta. Pero utilizaremos las propiedades de desplazamiento top y right para colocarlo en la esquina derecha.


/* Posiciona el signo más a 5px de la derecha. Lo centra utilizando la propiedad transform. */

.acordeon .etiqueta::before {
  content: '+';
  color: black;
  position: absolute;
  top: 50%;
  right: -5px;
  font-size: 30px;
  transform: translateY(-50%);
}

/* Oculta el contenido (altura: 0), disminuye el tamaño de la fuente, justifica el texto y añade la transición */

.acordeon .contenido {
  position: relative;
  background: white;
  height: 0;
  font-size: 20px;
  text-align: justify;
  width: 780px;
  overflow: hidden;
  transition: 0.5s;
}

/* Añade una línea horizontal entre los contenidos */

.acordeon hr {
  width: 100;
  margin-left: 0;
  border: 1px solid grey;
}

Esto hará que todo sea mejor. También observa que el contenido de cada lista está ahora oculto.

image-36
El contenido del menú acordeón está ahora oculto

Añadir JavaScript a nuestro Acordeón

En este punto, nuestro acordeón es bastante estático. Para hacer que el contenedor muestre el contenido cuando el usuario haga clic en él, necesitaremos introducir algo de JavaScript.

Navegue a su script app.js y escriba el siguiente código:

const acordeon = document.getElementsByClassName('contenedor');

for (i=0; i<acordeon.length; i++) {
  acordeon[i].addEventListener('click', function () {
    this.classList.toggle('activa')
  })
}

Este script accederá a todas nuestras listas por classname del contenedor.

Luego haremos un bucle a través de la lista. Para cada contenedor, simplemente queremos registrar un oyente de eventos en él. Cuando se hace clic, queremos cambiar la clase "activa" en ese elemento.

Ahora vamos a probar este efecto. Haz clic en el primer contenedor con la etiqueta ¿Que es HTML?, abre tus Herramientas de Desarrollador (haz clic en F12), e inspecciónalo dentro de la pestaña de elementos.

Deberías encontrar la clase activa registrada en él:

image-39

Si se vuelve a hacer clic en el elemento, se eliminará la clase activa del mismo.

Cómo finalizar la aplicación

Hay una última cosa que necesitamos hacer. Necesitamos crear una clase activa dentro de una hoja de estilos. Definiremos cómo queremos que se vea nuestro acordeón una vez que JavaScript active la clase en un contenedor.


/* Muestra la parte de contenido cuando está activa. Establece la altura */

.acordeon .contenedor.activa .contenido {
  height: 150px;
}

/* Cambia de signo positivo a negativo una vez activado */

.acordeon .contenedor.activa .etiqueta::before {
  content: '-';
  font-size: 30px;
}

Así es como se ve y se comporta nuestra aplicación al final:

Peek-2022-02-26-14-27
Aspecto final

Conclusión

Así que en este tutorial, construimos un menú acordeón usando HTML, CSS y JavaScript.

Gracias por seguirnos. Espero que hayas aprendido algo útil de este tutorial.

Que tengas una buena semana.