Cómo Crear un Componente de Acordeón con CSS y un Toque de JavaScript
Spanish (Español) translation by Carlos (you can also view the original English article)
En el tutorial de hoy, aprenderemos a crear un componente “muestra/oculta” con CSS y un poco de JavaScript. Por defecto, jQuery ofrece el método slideToggle que nos permite crear acordeones con un movimiento deslizante. Nuestro reto es imitar esta funcionalidad con puro JavaScript.
Aquí está el componente que crearemos:
Nota: esta es una funcionalidad proporcionada de manera nativa por los elementos details y summary, aunque estos no cuentan todavía con soporte en los navegadores de Microsoft.
1. El HTML
Para comenzar, definimos un elemento con la clase de container que contiene dos subelementos:
- el botón que ocultará y mostrará el contenido (incluido un icono de SVG en línea)
- el contenido real
Aquí está como se ve:
1 |
<div class="container"> |
2 |
<!-- other content here -->
|
3 |
|
4 |
<button class="toggle-btn"> |
5 |
<span class="more show"> |
6 |
Show More info |
7 |
<svg width="24" height="24" viewBox="0 0 24 24"> |
8 |
<path d="M0 7.33l2.829-2.83 9.175 9.339 9.167-9.339 2.829 2.83-11.996 12.17z"/> |
9 |
</svg>
|
10 |
</span>
|
11 |
<span class="less hide"> |
12 |
Show Less info |
13 |
<svg width="24" height="24" viewBox="0 0 24 24"> |
14 |
<path d="M0 16.67l2.829 2.83 9.175-9.339 9.167 9.339 2.829-2.83-11.996-12.17z"/> |
15 |
</svg>
|
16 |
</span>
|
17 |
</button>
|
18 |
|
19 |
<div class="info"> |
20 |
<!-- content here -->
|
21 |
</div>
|
22 |
|
23 |
<!-- other content here -->
|
24 |
</div>
|
2. El CSS
El CSS es muy sencillo. Necesitamos definir dos clases de ayuda (es decir, hide y show).
Para ocultar y mostrar el elemento objetivo, usaremos la propiedad height, pero no especificaremos sus valores en CSS. En cambio, ajustaremos dinámicamente los valores de la altura a través de JavaScript.
Una cosa a considerar es que no usamos la propiedad display para alternar la visibilidad de nuestro contenido. Esa propiedad no se cuenta entre las propiedades animatable de CSS.
Aquí están los estilos de CSS correspondientes:
1 |
.hide { |
2 |
display: none; |
3 |
}
|
4 |
|
5 |
.show { |
6 |
display: flex; |
7 |
}
|
8 |
|
9 |
.info { |
10 |
overflow: hidden; |
11 |
transition: height .5s; |
12 |
}
|
3. El JavaScript
Ahora es momento de discutir cómo debería funcionar nuestro código JavaScript.
Primero, tan pronto como el DOM esté listo, obtenemos la altura del elemento .info y luego ajustamos inmediatamente su valor a 0.
1 |
const info = document.querySelector(".info"); |
2 |
|
3 |
let infoHeight = info.offsetHeight; |
4 |
info.style.height = 0; |
Ten en cuenta que, dependiendo de tu contenido (por ejemplo, si incluye imágenes), puede que tengas que incluir el código anterior dentro del evento load.
Luego, cuando se hace clic en el botón .toggle-btn, hacemos lo siguiente:
- Alterna la visibilidad de los elementos
.lessy.more. - Recalcula la altura del elemento
.info. Si es 0 (inicialmente le damos este valor), eso significa que el contenido está oculto, así que lo revelaremos ajustando su altura igual a su altura inicial (almacenada en la variableinfoHeight). Por otro lado, si el contenido está visible, lo ocultamos ajustando su altura a 0. - Opcionalmente, nos aseguramos que el
.toggle-btnse hará clic una sola vez hasta que finalice la animación del deslizamiento (dura 500 ms).
Aquí está el código que implementa todo ese funcionamiento:
1 |
const toggleBtn = document.querySelector(".toggle-btn"); |
2 |
const info = document.querySelector(".info"); |
3 |
const less = document.querySelector(".less"); |
4 |
const more = document.querySelector(".more"); |
5 |
|
6 |
// initial height
|
7 |
let infoHeight = info.offsetHeight; |
8 |
|
9 |
toggleBtn.addEventListener("click", function() { |
10 |
this.disabled = true; |
11 |
|
12 |
more.classList.toggle("show"); |
13 |
more.classList.toggle("hide"); |
14 |
less.classList.toggle("show"); |
15 |
less.classList.toggle("hide"); |
16 |
|
17 |
const infoNewHeight = info.offsetHeight; |
18 |
if(infoNewHeight == 0) { |
19 |
info.style.height = `${infoHeight}px`; |
20 |
} else { |
21 |
info.style.height = 0; |
22 |
}
|
23 |
|
24 |
setTimeout(() => { |
25 |
this.disabled = false; |
26 |
}, 500); |
27 |
});
|
Tamaño del Navegador
El siguiente paso es asegurarte que el componente funcionará correctamente a medida que la ventana del navegador cambia su tamaño.
Aquí está el código de JS necesario:
1 |
// variable definitions here
|
2 |
|
3 |
window.addEventListener("resize", () => { |
4 |
info.style.removeProperty("height"); |
5 |
infoHeight = info.offsetHeight; |
6 |
if(more.classList.contains("hide")) { |
7 |
info.style.height = `${infoHeight}px`; |
8 |
} else { |
9 |
info.style.height = 0; |
10 |
}
|
11 |
});
|
4. Soporte del Navegador
Nuestra demostración debería trabajar bien en todos los navegadores y dispositivos recientes. Además, como siempre, utilizamos Babel para compilar el código ES6 a ES5.
Conclusión
En este breve tutorial creamos un componente “muestra/oculta” estilo acordeón con CSS y JavaScript. Gracias a la propiedad height animable, conseguimos añadir un efecto slide-in/slide-out a nuestro componente.
En particular, no hemos considerado la accesibilidad, por lo que si quieres mejorar su funcionalidad, sin duda podría ser el siguiente paso.
Más Tutoriales “Con un Toque de JavaScript”


JavaScriptCómo Crear un Componente de Pestañas Responsivo con CSS y un Toque de JavaScriptGeorge Martsoukos

Diseño de NavegaciónCómo Crear un Menu Off-Canvas con CSS y un Toque de JavaScriptGeorge Martsoukos

JavaScriptUna Técnica Simple de JavaScript para Rellenar Estrellas de CalificaciónGeorge Martsoukos

Diseño de NavegaciónCómo Crear un Efecto Hover de Subrayado Movedizo con CSS y JavaScriptGeorge Martsoukos





