Description
Panel Reveal is designed for content that expands within an existing card or section, such as a detail panel or a collapsible block of form fields. The panel travels a short distance on the Y axis while fading in and clearing a soft blur, so even a half-height travel reads as a complete open. Wrap it in a container with overflow: hidden to clip the closed state.
Example
CSS
:root {
--panel-open-dur: 400ms;
--panel-close-dur: 350ms;
--panel-translate-y: 100px;
--panel-blur: 2px;
--panel-ease: cubic-bezier(0.22, 1, 0.36, 1);
}
.t-panel-slide {
transform: translateY(var(--panel-translate-y));
opacity: 0;
filter: blur(var(--panel-blur));
pointer-events: none;
transition:
transform var(--panel-close-dur) var(--panel-ease),
opacity var(--panel-close-dur) var(--panel-ease),
filter var(--panel-close-dur) var(--panel-ease);
will-change: transform, opacity, filter;
}
.t-panel-slide[data-open="true"] {
transform: translateY(0);
opacity: 1;
filter: blur(0);
pointer-events: auto;
transition:
transform var(--panel-open-dur) var(--panel-ease),
opacity var(--panel-open-dur) var(--panel-ease),
filter var(--panel-open-dur) var(--panel-ease);
}
@media (prefers-reduced-motion: reduce) {
.t-panel-slide {
transition: none !important;
}
}
React
import { useState } from "react";
import "./panel-reveal.css"; // paste the CSS above
export function PanelReveal() {
const [open, setOpen] = useState(false);
return (
<div style={{ overflow: "hidden" }}>
<div
className="t-panel-slide"
data-open={open ? "true" : "false"}
style={{ "--panel-translate-y": "64px" } as React.CSSProperties}
>
<p>Shipping address</p>
<p>123 Main Street, Springfield</p>
</div>
<button onClick={() => setOpen((v) => !v)}>
{open ? "Close panel" : "Open panel"}
</button>
</div>
);
}
Variables
| Variable | Default | Notes |
|---|---|---|
--panel-open-dur | 400ms | sourced from --p3-open-dur |
--panel-close-dur | 350ms | sourced from --p3-close-dur |
--panel-translate-y | 100px | sourced from --p3-translate-y |
--panel-blur | 2px | sourced from --p3-blur |
--panel-ease | cubic-bezier(0.22, 1, 0.36, 1) | sourced from --p3-ease |
Credit
Adapted from Panel Reveal on transitions.dev by Jakub Antalik. Original source: github.com/Jakubantalik/transitions.dev.