shadcn.io is not affiliated with official shadcn/ui
The button sits a few pixels up on a darker edge of its own color. While it's pressed, the face drops onto the edge, and it comes back up on release, at once, the way a key gives under a finger.
Use it where pressing should feel physical: games, playful products, a keypad, a row of formatting toggles. In a dense, quiet interface a flat Button fits better; for press feedback that doesn't change the button's shape, use the Ripple Button. It wraps the Button, so variant and size work as usual, and each variant gets an edge in its own shade. It's CSS only: the edge is a shadow under the face, and the press moves the face down by the edge's height, with no transition and no JavaScript, so there's nothing for reduced motion to take away.
Installation
Usage
import { DepthButton } from "@/components/ui/depth-button";<DepthButton>Start game</DepthButton>Demos
Intensity
intensity sets how high the button stands and how far it drops: subtle is 3px, medium 5px and strong 7px, with medium by default. A subtle edge suits small buttons and toolbars; a strong one suits a big, single action.
Pressed
pressed holds the button down, which makes it the on state of a toggle. These formatting buttons keep pressed and aria-pressed in step, so the state shows and is announced. Pressing a held button still activates it.
Accessibility
The edge and the drop are visual. The button is announced and activated as any Button. pressed only changes the look: for a toggle, also pass aria-pressed, as the Pressed demo does, so screen readers say whether it's on.
- Enter
- Activate the button.
- Space
- Press the button down and activate it on release.
FAQ
How do I make it more or less raised?
Set intensity to subtle (3px), medium (5px, the default) or strong (7px). The button drops the same distance when pressed.
Can I keep it pressed, like a toggle?
Yes. Pass pressed and it stays down until you set it back. Pass aria-pressed with the same value so the state is announced, as in the Pressed demo.
Does it press down from the keyboard?
With Space, yes: the browser shows a button as pressed while Space is held, as it does for a pointer. Enter activates the button at once, with no held state to show.
Why does the face drop at once, without a transition?
Because the edge is a shadow, and a shadow can't follow a moving face without animating it on every frame. Dropping at once keeps the edge and the face in step, and it's how a real key feels: it gives as soon as you press it.
How is the edge colored, and can I change it?
Each variant gets a shade of its own color: the primary color mixed toward the foreground for the default, the border for outline, and so on, in both themes. To pick your own, set the --depth-button-edge variable in className, such as [--depth-button-edge:var(--ring)].
API Reference
DepthButton
focusableWhenDisabled?boolean
Whether the button should be focusable when disabled.
- Default
false
intensity?"subtle" | "medium" | "strong"
How high the button stands on its edge, and so how far it drops when
pressed: subtle is 3px, medium 5px, strong 7px.
- Type
"subtle" | "medium" | "strong"- Default
"medium"
nativeButton?boolean
Whether the component renders a native <button> element when replacing it
via the render prop.
Set to false if the rendered element is not a button (for example, <div>).
- Default
true
pressed?boolean
Hold the button down on its edge, as the on state of a toggle. Add
aria-pressed too when it is one, so the state is announced.
- Default
false
render?ReactElement | ((props: object, state: object) => ReactElement)
Replace the host element or compose it with another component.
- Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string
Merged with the part's classes.
data-down?string
Present when pressed is set.
--depth-button-depthstring
How high the button stands on its edge (5px).
--depth-button-edgestring
The edge's color (a shade of the variant's).
--depth-button-lightstring
The light line along the face's top.
Related
- Pro
Pill Button
SurfacesRounded with an inset highlight
Magnetic Button
Motion & feedbackMotion that follows the pointer
Ripple Button
Motion & feedbackA flat take on press feedback
- Pro
Long Press Button
ControlsHold down to confirm
- Pro
Glass Button
SurfacesAnother surface-style button
Icon Button
Hover revealsIcon buttons with an active state