DEV Community

Cover image for overlapui — avatars, cards, images, and circle menus that stack in pure CSS
FSCSS tutorial for FSCSS tutorial

Posted on Originally published at github.com

overlapui — avatars, cards, images, and circle menus that stack in pure CSS

You need a row of faces that sit on top of each other, a pile of notification cards, a tilted photo strip, or a “+” that fans into actions — and you don’t want a JS component library for the open/close motion.

overlapui.fscss is a small FSCSS module for that. Stacks overlap at rest and spread on hover/focus. Styling is driven by --ou-* tokens. No runtime JS for the interaction.

Source: github.com/fscss-ttr/overlapui.fscss

Requires: FSCSS 1.2.3+ (recommended 1.2.5+)


What’s in the box

Component Behavior
Avatar overlap Circles pull in; spread on hover/focus; data-alph → letter + color
Card overlap Cards peek under each other; expand on hover/focus
Image overlap Tilted photos; straighten and gap open
Circle overlap Center control; satellites fan on a ring (--n = count)

Install once:

@import((*) from overlapui)

@overlapui()
Enter fullscreen mode Exit fullscreen mode

Or only what you need:

@import((ou-root, ou-avatar-colors, avatar-overlap, circle-overlap, ou-reduced-motion) from overlapui)

@ou-root()
@avatar-overlap(.avatar-overlap)
@circle-overlap(.circle-overlap)
@ou-reduced-motion()
Enter fullscreen mode Exit fullscreen mode

CDN prototyping:

<script src="https://cdn.jsdelivr.net/npm/fscss@1.2.5/runtime.min.js" defer></script>
Enter fullscreen mode Exit fullscreen mode

Tokens, not magic classes

@ou-root() sets defaults like ring color, timing, avatar size, orbit radius. Override on :root or a wrapper:

:root {
  --ou-ring: #0f172a;
  --ou-size: 36px;
  --ou-center-bg: #6366f1;
  @ou-circle-size(48px, 80px)
}
Enter fullscreen mode Exit fullscreen mode

Same module, different product chrome.


Markup (short)

Avatars

<ul class="avatar-overlap" tabindex="0">
  <li data-alph="g">Gina</li>
  <li data-alph="h"><img src="…" alt="">Hank</li>
  <li data-alph="5">5001</li>
</ul>
Enter fullscreen mode Exit fullscreen mode

Circle menu — first child is center; --n is satellite count:

<div class="circle-overlap" style="--n:5" tabindex="0">
  <button type="button" aria-label="Menu">+</button>
  <a href="#">H</a>
  <a href="#">S</a>
  <a href="#">C</a>
  <a href="#">G</a>
  <a href="#">P</a>
</div>
Enter fullscreen mode Exit fullscreen mode

tabindex="0" so keyboard :focus-within works like hover.


Why FSCSS here

Avatar letter colors use FSCSS arrays to map data-alph (A–Z / 0–9) to a palette at compile time. Circle and stacks stay plain CSS after expand — fine for CLI output or the runtime. Prefer 1.2.5+ if you also use new features elsewhere in the app.


Real use cases

  • Members column in a dashboard table (avatar stack + name/role)
  • Notification pile without a drawer component
  • FAB / radial actions next to a profile strip
  • Photo strips on marketing or case-study pages

Full table example, card stack, and image strip: README.


Accessibility

  • Keep real names in the DOM for avatars (faces can hide the letter with font-size: 0).
  • Label the circle center and each action (aria-label).
  • @ou-reduced-motion() turns off the springy transitions when the user prefers reduced motion.

Sources

MIT. stack UI that opens with CSS.

Top comments (0)