shadcn.io is not affiliated with official shadcn/ui
When the pointer arrives or the button takes keyboard focus, a line starts at the left edge and runs once around the button until the outline is closed, with a soft glow. A faint fill of the same color comes up underneath. When the pointer leaves, the line draws itself back.
Use it for actions in developer tools and technical products, such as Deploy, Run or Generate, where a crisp line suits the interface better than a fill. For a ring that's always drawn and turns on hover, use the Flow Button. It wraps the Button and starts as a ghost button in the primary color, but any variant and size work. The line is a conic gradient under a ring-shaped mask, its sweep a CSS property a transition takes from 0% to 100%; the install registers that property in your stylesheet, with no animation library. Its corners are the button's own, whatever the radius. With reduced motion the outline appears at once.
Installation
Usage
import { BorderTraceButton } from "@/components/ui/border-trace-button";<BorderTraceButton>Deploy project</BorderTraceButton>Demos
Duration
duration is how long the line takes to go once around the button, in milliseconds, and the default is 600. It draws back at the same speed. A short trace suits a button people press often; a slow one turns hovering into a small moment.
Color
traceColor colors the line, its glow and the faint fill under it, any CSS color. By default they take the label's color, which is the primary color on the default ghost button. Here a filled button traces in its own label color, so the line shows on its edge, and a destructive action traces in var(--destructive).
Accessibility
The line and the fill are decoration and hidden from assistive tech: the button is announced and activated as any Button. The trace runs on keyboard focus as well as on hover, so people who tab through the page see the same cue.
- Enter
- Activate the button.
- Space
- Activate the button.
FAQ
How do I control how fast the line draws?
Set duration in milliseconds; 600 is the default. The line draws back at the same speed when the pointer leaves. The Duration demo shows 300 and 1500.
How do I change the color of the line?
Pass traceColor, such as var(--destructive). It colors the line, its glow and the fill under it. The Color demo shows two.
Do the corners match my button's radius?
Yes. The line is cut out of the button's own box with its own corners, so it follows your theme, every size and the pill prop. There's nothing to set or measure.
Does the outline stay after it's drawn?
While the pointer stays, or the button keeps keyboard focus, yes: the line holds, glowing softly. When the pointer leaves, it draws back from where it ended.
Why does the line run faster along the ends?
It sweeps around the button's center at an even turn, like a clock hand, so it crosses the short ends of a wide button quickly and takes its time along the long sides.
Can I use it with other variants and sizes?
Yes. It starts as a ghost button with a primary label, and you can pass any variant and size. The line takes the label's color, so it shows on a filled button too.
API Reference
BorderTraceButton
data-slot="border-trace-button-trace"
children?ReactNode
The label, inside the line.
duration?number
How long the line takes to go once around the button, in milliseconds; it draws back as fast when the pointer leaves.
- Default
600
focusableWhenDisabled?boolean
Whether the button should be focusable when disabled.
- Default
false
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
traceColor?string
The line's color, and the faint fill's under it, any CSS color. By default the label's color: the primary color on the default ghost button.
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.
--border-trace-button-colorstring
The line and the fill under it (the label's color by default).
--border-trace-button-durationstring
One trip around the edge (600ms).
--border-trace-button-progressstring
How much of the edge is drawn, 0% to 100%.
Related
- Pro
Glow Border Button
Glow & lightA ring that turns without end
- Pro
Flow Button
Glow & lightEdge light that turns on hover
- Pro
Stitch Button
SurfacesA dashed, stitched border instead
- Pro
Shimmer Button
SurfacesA shimmer running round the ring
- Pro
Neon Button
Glow & lightGlow without the drawing line
- Pro
Underline Button
Hover revealsDraws just one line under the label