Transition CSS de la propriété height de 0px à auto

Bonjour, Habr!

Je veux partager une autre façon de créer une transition css de la propriété height de 0px à auto .

Face à ce problème lors du développement de composants Web TreeView et DataGrid. Dans TreeView, j'ai décidé de faire une expansion / un effondrement en douceur des nœuds, et dans un DataGrid - des lignes avec du contenu supplémentaire. Après avoir lu Internet, j'ai trouvé plusieurs méthodes d'implémentation, les principales via la max-height et en javascript. L'implémentation javascript a été exclue - il existe des CSS avec prise en charge des transitions et des animations. max-height , en particulier dans les exemples de menus déroulants, tout fonctionne.

Dans TreeView, chaque nœud a une imbrication illimitée, vous ne pouvez donc pas déterminer immédiatement la hauteur maximale de son contenu, et même si vous définissez la max-height sur très grande, il y aura des problèmes avec l'animation de transition. De plus, si vous développez les nœuds enfants, la hauteur du parent augmentera et peut chevaucher max-height . Qu'on le veuille ou non, la max-height ne convient pas. DataGrid a le même problème - il peut y avoir n'importe quel contenu supplémentaire dans une rangée. Besoin de height:auto !

Commençons donc à implémenter la transition sur la propriété height de 0px à auto . Prenons un exemple simple.

Soit:

  • elBlock: HTMLDivElement - bloc à elBlock: HTMLDivElement / elBlock: HTMLDivElement ;
  • elToggle: HTMLButtonElement - bouton pour basculer le statut.

Définissez une classe css pour le bloc dans lequel nous définissons le découpage du contenu et la transition elle-même:

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

Nous décrivons le onClick événements elToggle pour 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"; } }); 

Reste à ajouter la height:auto retour height:auto après la transition:

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

Eh bien, c'est tout, maintenant l'expansion / l'effondrement du bloc fonctionne comme il se doit et ne dépend pas de la taille du contenu.


Figure 1 - Un exemple de développement / réduction de nœuds dans un TreeView

Il convient de noter les inconvénients de cette approche:

  • en utilisant javascript, je voudrais seulement css;
  • pendant la transition, le contenu (sa hauteur, scrollHeight ) peut changer et après son achèvement, si l' auto revient, la hauteur du bloc changera considérablement dans une direction ou une autre. Pour éviter cet effet, vous devez suivre le changement dans scrollHeight et changer la height . Comme le montre la pratique, les transitions expand / collapse prennent généralement 0,5 s chacune, et pendant ce temps, il est peu probable que l'utilisateur ait le temps de changer quelque chose à l'intérieur, par exemple, dans le cas de TreeView, développez le nœud enfant.

Merci de votre attention!

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


All Articles