Dotted Constellation Border
Dots placed along a box's edge float gently; on hover, focus or finger press they light up and link into a constellation.
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



How it works
On load, the script adds an SVG inside each .cst-box, overflowing by 10 px all round, then places dots about 36 px apart on the box's real edge: 20 at the default 200 × 120 px size, 29 at 320 × 160. Each dot strays from the edge by 2 px at most, and those offsets come from a pseudo-random generator set by data-cst-seed: the same seed always gives the same drawing, on every load and in every browser.
Each dot (2.5 px radius, #6366f1) floats by up to 2 px in a direction of its own, 3 s there and back, starting 0.15 s after its neighbour. The script also draws a line between all dots less than 70 px apart, but those lines stay invisible at rest.
On hover, focus (:focus-within) or finger press (cst-on class), the lines fade in over 0.3 s to 40% opacity and the dots turn #a78bfa with a 4 px glow: the constellation forms. If the box changes size, a ResizeObserver redraws so the dots stay on the edge.
Accessibility
- Silent decoration: the added SVG has
aria-hidden="true"andfocusable="false"; screen readers only read the box content. - Keyboard: the demo box is a
<div>. Put thecst-boxclass on a link or button, or place one inside, and Tab forms the constellation (it replaces the box's focus outline). On macOS Safari, Option+Tab reaches links if the system setting does not allow it with Tab. - Touch: a finger press forms the constellation until the next press elsewhere, WebKit included.
- Reduced motion: under
prefers-reduced-motion: reduce, dots stop floating and lines appear without fading; the dotted edge and the constellation remain. - Weak cue: 2.5 px dots and 40% lines are not enough to show focus on a light background; in that case, bring back an outline on your link's
:focus-visible.
Browser compatibility
SVG built in JavaScript (4.2 KB), :is() selector (Chrome 88, Firefox 78, Safari 14), ResizeObserver (Chrome 64, Firefox 69, Safari 13.1). Measured in Chromium 151, Firefox 153 and WebKit 26.5 (Playwright): two copies with only the second one hovered, script pasted twice without duplicate dots, same positions in all three browsers, box resized to 320 × 160 with 29 dots at most 4 px from the edge, keyboard focus, finger press, 390 px without overflow, reduced motion with no animation, 0 errors.
Without JavaScript, no dots: the box shows alone with its content. Without ResizeObserver, dots keep the size of the first drawing.
The code
HTML structure to paste into your page (the CSS + JS come with your purchase):
<div class="fx-0774-root">
<div class="cst-box" data-cst-seed="7">
…
<!-- the script adds <svg class="cst-svg"> with the .cst-link and .cst-dot -->
</div>
</div>
One-time payment, no subscription — the code is yours forever
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
Seed (HTML — data-cst-seed on .cst-box) |
7 |
Whole number that sets the dots' small offsets and their float direction. Change it to vary the drawing from one box to the next. |
Colours (CSS — --cst-color, --cst-color-active, --cst-glow) |
#6366f1, #a78bfa, rgba(99, 102, 241, .8) |
Dots and lines at rest, dots in the active state, dot glow. |
Gap between dots (JS — SPACING) |
36 px |
Smaller means more dots; eight dots minimum at any size. |
Link length (JS — LINK) |
70 px |
Longest distance between two linked dots. Keep it around twice SPACING. |
Box size (CSS — width / min-height of .cst-box) |
at least 200 × 120 px | Dots follow the edge at any size and move back into place when it changes. |
Forced active state (HTML — cst-on class) |
absent | Keeps the constellation formed, for instance on the chosen item. The script only removes the one it added on touch. |
FAQ
Math.random() the drawing changed on every visit and a screenshot never matched the page. The seed makes the result identical everywhere while keeping an irregular look. For different drawings on one page, give each box a different seed.LINK to about 40 px to keep only the links along the edge.cst-box class on the card's <a> and your content inside; the script appends its SVG at the end. Hover, Tab and a finger press form the constellation, and the card stays an ordinary link. Keep one .fx-0774-root per card: the script only draws the first .cst-box of each root.