Marching Border
Animated dashed border overlay that conforms to its parent's corner radius
Preview
Bundle: Reading list
3 unsaved changes. Confirm to publish, or discard to revert.
Installation
Usage
MarchingBorder renders as an absolutely-positioned SVG overlay. Drop it inside any positioned parent (position: relative or another positioned ancestor) with a rounded-* class, and the dashed border conforms to that radius automatically. Because the overlay lives outside the parent's box model, toggling it on or off causes zero layout shift — useful for staged edit states, pending changes, drag-over indicators, and similar pattern-driven UI signals.
Color comes from currentColor — set it via a Tailwind text-* class on the SVG itself.
Examples
Variants
Tune dash, gap, strokeWidth, and duration for different visual moods. dash and gap are expressed as percentages of the path's perimeter, so the pattern tiles consistently across element sizes.
Explicit radius
When the parent doesn't carry a rounded-* class — for example, a <canvas> or a custom-shaped panel — set radius directly. Pass 0 for a perfectly rectangular border.
API Reference
MarchingBorder is a single SVG component. It accepts any native <svg> prop in addition to those documented below; spread props land on the root <svg> element.
Props
Notes
- Parent positioning. The SVG is
absolute inset-0, so the parent must be positioned (relative,absolute,fixed, orsticky). Without that, the border attaches to the nearest positioned ancestor instead. - Seam-free loop.
pathLengthis rounded to a whole multiple ofdash + gap, so the pattern tiles around the perimeter an exact integer number of times regardless of element size. The path also starts at the midpoint of the top edge so any residual subpixel error sits on a straight side rather than a corner. - Shared keyframe. A single
@keyframes dash-marchrule is shared across every instance via an inline<style>. The end offset is driven by a per-instance CSS variable on the path, so changingdash/gapdoesn't generate new keyframes. - Reduced motion. Under
prefers-reduced-motion: reducethe marching animation is suppressed, but the dashed border itself still renders — for an edit-mode signal, the static dashes are the primary cue and shouldn't disappear entirely. - Color. The stroke uses
currentColor. Set the color with a Tailwindtext-*class (e.g.text-primary,text-destructive) directly on the component.