This is an Animated Border Drawing Button. It transforms a standard call-to-action into a multi-stage micro-interaction. Upon hovering over the button, the component triggers a sequential animation where four corner dots appear, followed by four dashed border lines that “draw” themselves around the button’s perimeter, creating a high-end, futuristic feel.
Specs
- Weight: ~3 KB. No external frameworks or JavaScript.
- Performance: High. The entire animation sequence is handled by native CSS keyframes targeting hardware-accelerated properties like
transform: scale()andopacity. - Theming / Customization: Easily configured via CSS custom properties. You can modify
--dot-size,--line-weight,--animation-speed, and color variables directly in the stylesheet. - Responsiveness: Inherently responsive. Uses relative units (
rem) to scale cleanly with the parent font size. - Graceful Degradation: [!] Relies heavily on the
:has()pseudo-class to trigger animations. In unsupported browsers, the button remains static and functional, but the border-drawing effect will not activate on hover.
Anatomy
The component uses a layered wrapper structure to separate the button from its decorative animated border.
- HTML (The Skeleton): A
.btn-wrappercontains the core<button>and a series ofdivelements for the.lineand.dotcomponents. - CSS (The Skin): Leverages
position: absoluteto stack the lines and dots around the button. The dotted line effect is created using arepeating-linear-gradient. - JS (The Nervous System): Completely absent. The state logic is managed by CSS.
Logic
The standout technical feature is “Staggered Animation Triggering with :has()”.
.btn-wrapper:has(.btn:hover) .dot.top.left {
animation: move-top-left var(--animation-speed) ease-in-out forwards;
}
.btn-wrapper:has(.btn:hover) .dot.top.right {
animation-delay: calc(var(--animation-speed) * 0.6);
}
.btn-wrapper:has(.btn:hover) .line.top {
animation-delay: calc(var(--animation-speed) * 0.8);
}
Instead of using JavaScript to orchestrate the animation sequence, the developer uses the :has() pseudo-class to create a powerful CSS-only trigger. The selector reads: “When the .btn-wrapper contains a hovered button…”. This single state change then cascades down to all the child dot and line elements. By applying different animation-delay values to each child, a complex, beautifully timed sequence is executed purely by the CSS engine, creating the illusion of a single, continuous drawing motion.
Feel
Precise, futuristic, and rewarding. The animation doesn’t just happen — it builds. The staggered appearance of the corner dots establishes the boundaries, and then the lines satisfyingly connect them. The slight rotation on the line animations as they scale in adds a subtle touch of organic imperfection to an otherwise rigid geometric sequence. It feels like a high-tech interface booting up or locking onto a target.


