Entry 04
Reveal with clip-path
Use it for dropdowns, menus and panels that open over the page and whose height is not known. It unrolls the panel without animating height, and it works in every browser.
Code
.menu {
clip-path: inset(0 -3rem 100%);
visibility: hidden;
}
.menu.is-open {
clip-path: inset(0 -3rem -3rem);
visibility: visible;
}
@media (prefers-reduced-motion: no-preference) {
.menu {
transition:
clip-path 0.25s var(--ease-out, ease-out),
visibility 0.25s;
}
}Why it works, the rules and the credits
Why it works
inset()clips from each edge, in the order top, sides, bottom. A bottom value of100%hides the whole box. The percentage refers to the element's own height, so nothing has to measure it.- A negative inset widens the clip beyond the box. That leaves room for the shadow at the sides and the bottom. The top stays at
0, so no shadow shows where the menu meets its trigger. - Layout never changes. The panel has its full size the whole time and nothing around it moves.
- The clipped part takes no pointer events, so a closed menu cannot be clicked.
visibilityin the transition switches tohiddenonly when the close has finished. That takes the links out of the tab order.
Rules
- The negative inset must be larger than the shadow's blur plus its offset.
- Use it for panels that overlap the page. A closed panel in the normal flow leaves a gap, so an accordion uses Accordion that animates its height.
- Add
roundwith a radius insideinset()only when the clip itself should have round corners. The element's ownborder-radiusstill applies.
Support
Every browser.
Credits
Borrowed from: Stripe, in the navigation menu on stripe.com. The visibility part was added for this list.
Docs: MDN: inset()