Introduction
Il est impossible de faire une transition sur height
entre 0
et auto
.
En revanche, il est tout à fait possible de faire une transition sur
grid-template-rows
entre 0fr
et 1fr
.
Code
<!--
La classe `expand` sert de sélecteur à la fonctionnalité.
Tout ce qui est en dehors ne sera pas affecté.
La variable --duration sera utilisée pour régler la durée de l'animation.
-->
<div class="expand" style="--duration:.2s;">
<!--
Nous allons utiliser cette checkbox pour stocker l'état ouvert/fermé de l'expand.
Et comme le label entoure la checkbox, un simple clic sur ce label aura pour effet de
basculer l'état de l'expand.
-->
<label>Click on me ! <input type="checkbox" /></label>
<!-- Cette div sera celle qui changera de hauteur de manière fluide pour l'animation -->
<div class="wrapper">
<!-- On peut avoir n'importe quelle hauteur de contenu, l'animation sera fluide dans tous les cas -->
<div class="content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed hendrerit at
nulla in interdum. Donec sit amet porttitor ipsum, non fermentum risus.
Phasellus vel enim at sapien aliquet sagittis. Aliquam quis massa dolor.
Nunc fermentum sagittis nulla id sollicitudin. Mauris blandit semper
metus, quis ullamcorper mauris tempus at. Integer pharetra massa tincidunt
accumsan semper. Donec libero lacus, sollicitudin sed nulla eget, molestie
consequat eros. Duis molestie lacinia dui ac cursus. Aliquam magna neque,
faucibus et venenatis ut, luctus pulvinar risus. Mauris lacinia, elit quis
dictum porta, mauris erat pulvinar dui, vitae hendrerit quam purus sed
nulla. Donec in ultrices sapien. Pellentesque posuere massa neque, eu
iaculis urna tristique ac.
</div>
</div>
</div>
<style>
/* Premièrement, on cache la checkbox */
.expand input {
display: none;
}
/* Ensuite, on applique un display grid qui va faire la transition entre la hauteur 0 et auto */
.expand .wrapper {
display: grid;
/* On définie la hauteur par defaut à 0 */
grid-template-rows: 0fr;
/* On applique une transition en prenant la variable duration en paramettre */
transition: grid-template-rows var(--duration) ease-out;
/* On cache bien tout ce qui sort de la box du wrapper: le contenu de l'expand */
overflow: hidden;
}
/* On force le contenu à prendre de la place dans le wrapper */
.expand .content {
min-height: 0;
}
/* On definie la hauteur à auto (1fr) quand la checkbox dans l'expand est cochée */
.expand label:has(input:checked) ~ .wrapper {
grid-template-rows: 1fr;
}
</style>