Transición CSS de la propiedad de altura de 0px a auto

Hola Habr!

Quiero compartir otra forma de crear una transición CSS de la propiedad de height de 0px a auto .

Enfrenté este problema al desarrollar componentes web TreeView y DataGrid. En TreeView, decidí hacer una expansión / colapso suave de los nodos, y en un DataGrid - filas con contenido adicional. Después de leer Internet, encontré varios métodos de implementación, los principales a través de la max-height y en javascript. Se descartó la implementación de JavaScript: hay CSS con soporte para transiciones y animaciones. max-height restante, especialmente en los ejemplos con menús desplegables, todo funciona.

En TreeView, cada nodo tiene un anidamiento ilimitado, por lo que no puede determinar inmediatamente la altura máxima de su contenido, e incluso si establece la max-height en muy grande, habrá problemas con la animación de transición. Además, si expande los nodos secundarios, la altura del padre aumentará y puede superponerse max-height . Nos guste o no, max-height no max-height adecuada. DataGrid tiene el mismo problema: puede haber contenido adicional en una fila. Necesita height:auto !

Entonces, comencemos a implementar la transición en la propiedad de height de 0px a auto . Considere un ejemplo simple.

Dejar:

  • elBlock: HTMLDivElement - bloque para elBlock: HTMLDivElement / contraer;
  • elToggle: HTMLButtonElement : botón para alternar el estado.

Defina una clase css para el bloque en el que establecemos el recorte del contenido y la transición en sí:

 .block { overflow: hidden; transition: height 500ms ease; } 

Describimos el onClick eventos onClick para elToggle :

 elToggle.addEventListener("click", () => { if (elBlock.style.height === "0px") { elBlock.style.height = `${ elBlock.scrollHeight }px` } else { elBlock.style.height = `${ elBlock.scrollHeight }px`; window.getComputedStyle(elBlock, null).getPropertyValue("height"); elBlock.style.height = "0"; } }); 

Queda por agregar la height:auto retorno height:auto después de la transición:

 elBlock.addEventListener("transitionend", () => { if (elBlock.style.height !== "0px") { elBlock.style.height = "auto" } }); 

Bueno, eso es todo, ahora la expansión / colapso del bloque funciona como debería y no depende del tamaño del contenido.


Figura 1 - Un ejemplo de nodos expandibles / colapsados ​​en un TreeView

Vale la pena señalar las desventajas de este enfoque:

  • usando javascript, me gustaría solo css;
  • durante la transición, el contenido (su altura, scrollHeight ) puede cambiar y después de su finalización, si regresa auto , la altura del bloque cambiará dramáticamente en una dirección u otra. Para evitar este efecto, debe realizar un seguimiento del cambio en scrollHeight y cambiar la height . Como muestra la práctica, generalmente las transiciones de expansión / colapso toman 0.5 s cada una, y durante este tiempo es poco probable que el usuario tenga tiempo de cambiar algo adentro, por ejemplo, en el caso de TreeView, expanda el nodo secundario.

Gracias por su atencion!

Source: https://habr.com/ru/post/475520/


All Articles