Transição CSS da propriedade height de 0px para auto

Olá Habr!

Eu quero compartilhar outra maneira de criar uma transição css da propriedade height de 0px para auto .

Enfrentou esse problema ao desenvolver componentes da Web TreeView e DataGrid. No TreeView, eu decidi fazer uma expansão / colapso suave de nós e em um DataGrid - linhas com conteúdo adicional. Depois de ler a Internet, encontrei vários métodos de implementação, os principais através da max-height e em javascript. A implementação do javascript foi descartada - há CSS com suporte para transições e animações. max-height restante, especialmente nos exemplos com menus suspensos, tudo funciona.

No TreeView, cada nó tem aninhamento ilimitado, portanto você não pode determinar imediatamente a altura máxima de seu conteúdo e, mesmo que você defina a max-height como muito grande, haverá problemas com a animação de transição. Além disso, se você expandir os nós filhos, a altura do pai aumentará e poderá se sobrepor max-height . Goste ou não, max-height não max-height adequada. O DataGrid tem o mesmo problema - pode haver qualquer conteúdo adicional em uma linha. Precisa de height:auto !

Então, vamos começar a implementar a transição na propriedade height de 0px para auto . Considere um exemplo simples.

Vamos:

  • elBlock: HTMLDivElement - bloco a ser elBlock: HTMLDivElement / recolhido;
  • elToggle: HTMLButtonElement - botão para alternar o status.

Defina uma classe css para o bloco em que definimos o corte do conteúdo e a própria transição:

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

Descrevemos o 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"; } }); 

Resta adicionar a height:auto retorno height:auto após a transição:

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

Bem, isso é tudo, agora a expansão / colapso do bloco funciona como deveria e não depende do tamanho do conteúdo.


Figura 1 - Um exemplo de expansão / recolhimento de nós em um TreeView

Vale ressaltar as desvantagens dessa abordagem:

  • usando javascript, gostaria apenas de css;
  • durante a transição, o conteúdo (sua altura, scrollHeight ) pode mudar e, após a conclusão, se o retorno auto , a altura do bloco mudará drasticamente em uma direção ou outra. Para evitar esse efeito, você precisa acompanhar a alteração no scrollHeight e alterar a height . Como mostra a prática, geralmente as transições de expansão / recolhimento levam 0,5 s cada e, durante esse período, é improvável que o usuário tenha tempo para alterar algo interno, por exemplo, no caso do TreeView, expanda o nó filho.

Obrigado pela atenção!

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


All Articles