My collapsible had a bug that I think most people would never consciously see. They'd only feel that the animation wasn't quite right.
Every time it opened, the last frame jumped by 4px.
Where the 4px came from
A nice collapsible does two things at once. The panel's height grows, and the content inside fades in while sliding down a little. In HextaUI, it starts 4px up.
To animate the height, you need to know the final height, so you measure the content. But I was measuring it while it was shifted up, so the panel worked out a height 4px too short.
So it animated to the wrong height, then corrected itself once the animation finished.
- Content starts 4px up
- Panel measures the shifted box
- Animates short
- Snaps 4px
- Clip layer holds the slide
- Panel measures the real box
- Animates to the right height
The fix was to add one more layer. It clips the sliding content, so the slide happens inside a box the panel doesn't measure. Once the panel has settled, the clip lets go.
The gap nobody animates
The other bug is easier to see, and it's probably in your app right now.
Put a collapsible in a flex column with a gap. Close it. The panel has no height, but it's still an item in the column, so it still gets its gap.
So when it closes, HextaUI's panel works out which gap it's responsible for and removes it too. That takes more thought than I'd expected:
- It only applies to flex columns and single-column grids, since a row's gap goes sideways.
flex-direction: column-reverseswaps which side the gap is on.- The first item has no gap before it, so it takes the one after instead.
- If the panel is wrapped in elements with
display: contents, its real parent is further up the tree, so the code has to walk up to find it.
That last one is real code, and it's the kind of case you only find when a wrapper breaks the fix.
function getLayoutItem(panel: HTMLElement) {
let item = panel;
let parent = panel.parentElement;
while (parent && getComputedStyle(parent).display === "contents") {
item = parent;
parent = parent.parentElement;
}
return { item, parent };
}
Slow everything down
You can't see either bug at normal speed, but you can feel both. The only way I know to find these is to slow the animation right down, and watch the first and last frames.
Most animation problems are at the ends. The middle moves too quickly to judge, but the ends are where things come to rest, and that's what your eye catches.