The task here is to cut what is below a certain height without breaking what is inside.
We can't just animate height. Some cases like CSS columns can be broken.
So we first measure the height of the component as it is and the set the value as
style="height: ..."; on .clipped__content
Next, on the .clipped__viewport wrapping div, we run the height animation from a certain canonical height that we set earlier to the value that we got. Actually we just change the height values here. The animation will be run by CSS when value changed.
data-canonical-height -- height we want to see on the page when clipped.
data-actual-height -- height of content inside.
.clipped--expandable -- this class is being added if we need clipping from the first place. If this class is not presented, no JS will be run. Also read more button visibility depends on this class.
.clipped--open -- when expanded. We need to know what animation to run: from canonical height to actual or vise versa. Also read more button appearance is based on it (more/less, angle).
See sample: ../scripts/_clipped.js