Tengo un contenedor como encabezado de un menú desplegable plegable con una altura máxima de 30 px. Estoy alternando una clase ".open" que cambia la altura máxima a 30000px onClick en Javascript.
Estoy tratando de agregar una transición CSS para que esto sea más fluido a través de la transición: 1s; a la clase de contenedor. El efecto resultante es torpe y parece incorrecto: el div colapsará instantáneamente (sin entrada/salida gradual) después de un tiempo de espera igual a los 1 en el elemento css. Es decir, si agrego la transición: 5 s;, no sucederá nada en la página hasta 5 s, luego el div se cerrará.
Espero que esto tenga sentido, ¡gracias!
-- Compartir código para mayor claridad:
html:
<section class="project"> <div class="project-head"> imgs/text with flexbox/grids etc </div> </section>CSS:
section.project { max-height: 30px; overflow: hidden; transition: all 0.5s ease-in-out; } .project-head { display: grid; height: 50px; width: 95vw; transition: .01s; } .open { max-height: 100000px !important; }js:
document.querySelectorAll('.project-head').forEach(project => { project.addEventListener('click', function () { this.parentElement.classList.toggle("open"); }); })El código está haciendo lo que se le ha pedido que haga: la transición de la altura máxima de algo muy grande a algo bastante pequeño. Es solo la última parte de eso lo que realmente verá y parece instantáneo porque la mayor parte del tiempo de transición se ha dedicado a reducir la enorme altura máxima a la altura real del div.
Este fragmento demuestra una mitigación del problema al poner la altura máxima en algo que no es tan alto. El div externo está configurado para tener un color diferente en la altura máxima más pequeña de la más grande para que pueda ver lo que está sucediendo:
document.querySelectorAll('.project-head').forEach(project => { project.addEventListener('click', function() { this.parentElement.classList.toggle("open"); }); }) section.project { max-height: 30px; overflow: hidden; transition: all 5s ease-in-out; background-color: rgba(255, 0, 0, 0.5); } .project-head { display: grid; height: 50px; width: 95vw; transition: .01s; } section.project.open { max-height: 100px; background-color: cyan; } <section class="project"> <div class="project-head"> imgs/text with flexbox/grids etc </div> </section>Ahora intente cambiar la altura máxima a algo mucho más grande y verá que su transformación no es tan notable, porque en su mayoría está fuera de la pantalla.
document.querySelectorAll('.project-head').forEach(project => { project.addEventListener('click', function() { this.parentElement.classList.toggle("open"); }); }) section.project { max-height: 30px; overflow: hidden; transition: all 5s ease-in-out; background-color: rgba(255, 0, 0, 0.5); } .project-head { display: grid; height: 50px; width: 95vw; transition: .01s; } section.project.open { max-height: 10000px; background-color: cyan; } <section class="project"> <div class="project-head"> imgs/text with flexbox/grids etc </div> </section>La expansión parece ser mucho más rápida y la contracción mucho más lenta.
¿Qué hacer en la práctica? Como bien dice, no puede hacer la transición de/a automático, por lo que la forma de altura máxima es una especie de forma de evitarlo. Parece que no hay otra forma que elegir una altura máxima sensata que probablemente sea un poco más que la altura total que desea exponer. Esto probablemente sea factible para un elemento en un menú, ya que consistirá en (muy) pocas líneas de texto. Sin embargo, si tiene muchas imágenes, esto puede ser más difícil de juzgar. Supongo que una forma sería hacer que JS calcule las alturas en tiempo de ejecución, pero eso anula el objeto de usar el método de altura máxima.