Marching Border
Animated dashed border overlay that conforms to its parent's corner radius
MarchingBorder is an animated dashed border overlay that conforms to its parent's corner radius. Use it to signal edit states, pending changes, or drag-over targets without shifting layout, since it sits outside the parent's box model.
Preview
Bundle: Reading list
3 unsaved changes. Confirm to publish, or discard to revert.
Installation
Usage
MarchingBorder is an absolutely-positioned SVG overlay. Put it inside a positioned parent (anything with position: relative, or another positioned ancestor) and it picks up that element's border-radius automatically, so the dashes follow rounded corners. It sits outside the parent's box model, so showing or hiding it never shifts layout. Handy for edit states, pending changes, and drag-over indicators.
The stroke uses currentColor, so set the color the same way you'd set text color: a text-* class, a color style, or inheriting from an ancestor.
Examples
Variants
Adjust dash, gap, strokeWidth, and duration to tune the pattern; dash and gap are percentages of the perimeter, so it tiles evenly at any size.
Overriding the radius
Set a border-radius on the overlay itself when it should differ from the parent, or when the parent has none (a canvas, a square panel); by default it inherits the parent's corners.
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 needs to be positioned (relative,absolute,fixed, orsticky). Otherwise the border attaches to the nearest positioned ancestor. - Seam-free loop.
pathLengthis rounded to a whole multiple ofdash + gap, so the pattern tiles an exact number of times at any size. The path starts at the middle of the top edge, so any subpixel seam lands on a straight side instead of a corner. - Shared keyframe. One
@keyframes dash-marchrule is shared across every instance. The end offset comes from a per-instance CSS variable, so changingdashorgapdoesn't generate new keyframes. - Reduced motion. Under
prefers-reduced-motion: reducethe animation stops but the dashes still render, since the static border is the actual signal and shouldn't vanish. - Color. The stroke is
currentColor. Set the color like text color, for example atext-*class such astext-primaryortext-destructiveon the component.