Utilities✨ Premium

Border Draw-On

On hover, focus or finger press, a 3 px line runs around the box in four steps from the top-left corner, then pulls back when the state ends.

CSSHoverSequential

Updated

This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. Utilities has 43 effects, including 3 free. Explore the category →

3 usage examples

Collection of a wallpaper maker — Border Draw-On example 1

① Collection of a wallpaper maker

WhenOn Mirvaude's site, six wallpaper patterns (a mural, a stripe, a grid check, straight and half-drop matches) form a grid of thumbnails. The one under the mouse gets an indigo line running all the way around it.
WhyThe drawn frame brings movement to a plain grid without touching the patterns, which are the real content. It follows the eye from one thumbnail to the next and pulls back on its own.
Settingsbdw-box on each thumbnail's <a> (one root per pattern), white background, --bdw-color: #4f46e5, --bdw-speed: .3s (1.2 s for the full lap). The capture adds the bdw-on class to one thumbnail after another to show the full drawing; the real mouse hover also draws the ones it crosses.
"Book an appointment" button for a dog groomer — Border Draw-On example 2

② "Book an appointment" button for a dog groomer

WhenAt the top of Varnelle grooming's site, under the heading "Bath, trim, claws: one appointment, one happy dog", the white "Book an appointment" button gets a green frame on hover or when reached with Tab.
WhyA quiet white button leaves room for the heading and the illustration; the frame drawing itself confirms that it responds, to the mouse as to the keyboard, without a bright colour.
Settingsbdw-box on a 46 px tall <a>, white background and light grey hairline at rest (scene CSS), --bdw-color: #2f7d62, --bdw-speed: .25s. The capture gives the button focus for 1.8 s, then takes it away.
Newsletter sign-up field — Border Draw-On example 3

③ Newsletter sign-up field

WhenIn La Gazette Ferrandine's sign-up panel, the "Your email address" field gets a brown line around it as soon as you click into it or reach it with the keyboard, and the frame pulls back when you leave.
WhyThe frame closing around the field clearly shows where to type without changing the layout, and the short movement stops as soon as the lap is done.
Settingsbdw-box around the <input> (triggered by :focus-within), 44 px tall, --bdw-color: #9b5b2b, --bdw-width: 2px, --bdw-speed: .15s (0.6 s per lap). The capture puts focus in the field and types an address.

How it works

The .bdw-box holds four empty <span class="bdw-line">, absolutely positioned on its edges: bdw-top starts at the top-left corner with zero width, bdw-right at the top-right corner with zero height, bdw-bottom at the bottom-right corner, bdw-left at the bottom-left corner. At rest nothing shows: the box has the same background as the page.

In the active state each line grows to 100% of its side in 0.4 s (cubic-bezier(.65, 0, .35, 1) curve), starting 0, 0.4, 0.8 and 1.2 s apart: the top draws left to right, then the right side goes down, the bottom comes back left and the left side climbs up. The whole frame is there after 1.6 s, with a 10 px box-shadow glow. When the state ends the lines retract in the same order, top first.

The active state combines hover, :focus-within (the box itself when it is a link or a button, or a field, link or button inside it) and the bdw-on class, which a 0.8 KB script adds when a finger or pen presses the box and removes at the next press elsewhere. Colour, thickness and the duration of one side are CSS custom properties.

Accessibility

  • Silent lines: the four <span> are empty and marked aria-hidden="true"; only your content is announced.
  • The drawing is the focus indicator: on a link or button, the box draws itself on keyboard focus and its default focus outline is removed (outline: none on :focus-visible). Keep a line colour with strong contrast against the background. Around an input field, the frame draws as soon as the field is active.
  • Touch: a finger press draws the frame (bdw-on class) and it stays until the next press elsewhere, even in WebKit, which has no hover.
  • Reduced motion: under prefers-reduced-motion: reduce there is no progressive drawing; the whole frame appears and disappears at once.
  • macOS Safari: Tab only reaches links if the system setting allows it; Option+Tab always does.

Browser compatibility

CSS (width and height transitions, custom properties, :is() selector: Chrome 88, Firefox 78, Safari 14), plus 0.8 KB of JavaScript for touch. Measured in Chromium 151, Firefox 153 and WebKit 26.5 (Playwright): two copies with only the second one hovered, keyboard focus through a link inside and through the box turned into a link, finger press, 390 px without overflow, reduced motion with no transition, 0 errors.

Chrome 88+✓ Full (measured)
Firefox 78+✓ Full (measured)
Safari 14+✓ Full (measured in WebKit)
Edge 88+✓ Full (Chromium engine)
Mobile iOS 14+✓ WebKit engine, not checked on a device
Android Chrome 88+✓ Full (Chromium engine)

A browser without :is() ignores the active-state rules: the box stays frameless. Without JavaScript, only a finger press on a box that is neither a link nor a button draws nothing.

The code

HTML structure to paste into your page (the CSS + JS come with your purchase):

index.html — structure
<div class="fx-0768-root">
  <div class="bdw-box">
    <span class="bdw-line bdw-top" aria-hidden="true"></span>
    <span class="bdw-line bdw-right" aria-hidden="true"></span>
    <span class="bdw-line bdw-bottom" aria-hidden="true"></span>
    <span class="bdw-line bdw-left" aria-hidden="true"></span>
    …
  </div>
</div>

One-time payment, no subscription — the code is yours forever

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
Line colour (CSS — --bdw-color) #6366f1 Colour of the four lines, set on .fx-0768-root or a parent.
Glow (CSS — --bdw-glow) rgba(99, 102, 241, .6) Colour of the 10 px halo in the active state; transparent for a line without halo.
Thickness (CSS — --bdw-width) 3px Thickness of all four lines.
Duration of one side (CSS — --bdw-speed) .4s Each side takes this long and waits for the previous one: the full lap lasts four times the value.
Box size (CSS — width / min-height of .bdw-box) 200 px wide, at least 120 px tall The lines use percentages: they fit any size.
Forced active state (HTML — bdw-on class on .bdw-box) absent Keeps the frame drawn, for instance on the current tab or project; adding or removing it replays the drawing. The script only removes the one it added on touch.

FAQ

The lines are straight bars stuck to the box edges; only their ends have a 3 px radius. If your box has a visible background and large rounded corners, bring its border-radius down to 4 px or less so the frame hugs its corners.
Yes, in CSS only: each line grows from the edge it is anchored to (left: 0 for the top, top: 0 for the right…) and in the order set by its transition-delay. Swap the anchors (right: 0 instead of left: 0) and the delays to change the starting point or the direction.
Put the bdw-box class on the card's <a>, keep the four <span> first and your content after them. Hover, Tab and a finger press draw the same frame, and the link stays an ordinary link for screen readers. One .fx-0768-root per card: the touch script only takes the first box of each root.