Utilities✨ Premium

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.

SVGJSInteractive

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

The twelve signs on a horoscope site — Dotted Constellation Border example 1

① The twelve signs on a horoscope site

WhenOn Astrévane's weekly page, the twelve signs form a grid of cards on a night sky, each edged with dots. The card under the mouse links its dots into a constellation.
WhyThe dots draw a starry sky around each sign, in keeping with the subject, and the forming constellation shows which card is targeted without changing the grid.
SettingsOne root per sign, cst-box on the card's <a> (76 px tall), data-cst-seed from 1 to 12 so each card has its own drawing; --cst-color: #a09ef8, --cst-color-active: #eeebff. Hover comes from the capture's mouse.
Show times panel at the top of a planetarium's page — Dotted Constellation Border example 2

② Show times panel at the top of a planetarium's page

WhenUnder the Corvelune Planetarium menu, a large "This week under the dome" panel lists three shows (northern sky, Saturn's rings, little explorers) with a Book button. Its dots float all the time and link up when the mouse enters the panel.
WhyAt a large scale the frame becomes the page's backdrop: a quiet sky around the key text, which comes alive when you take an interest.
Settings380 × 250 px cst-box, left-aligned content, translucent navy background; data-cst-seed="21", --cst-color: #93a8ff, --cst-color-active: #e4ebff. The button inside also forms the constellation on keyboard focus.
Unlocked level badge in a learning app — Dotted Constellation Border example 3

③ Unlocked level badge in a learning app

WhenOn Léonie's profile in the Savellio app, a row of badges sums up her Italian lessons. When she unlocks level 5 (past tense), the badge links into a constellation and a dark notification appears below.
WhyThe forming constellation marks the event on a small item without an abrupt animation, and the dots stay around the badge as a trace of the achievement.
Settings112 × 92 px cst-box (14 dots), data-cst-seed="5", --cst-color: #7c6cf0. The scene adds the cst-on class on unlock and removes it to start over. On a box this small, some lines cross the corners inside.

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" and focusable="false"; screen readers only read the box content.
  • Keyboard: the demo box is a <div>. Put the cst-box class 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.

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)

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):

index.html — structure
<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 / propertyDefaultEffect
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

With 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.
Links reach 70 px. Near the corners of a box under about 150 px, dots on two neighbouring sides are close enough to be linked diagonally. On a badge or icon, lower LINK to about 40 px to keep only the links along the edge.
Put the 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.