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()
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()
CDN prototyping:
<script src="https://cdn.jsdelivr.net/npm/fscss@1.2.5/runtime.min.js" defer></script>
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)
}
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>
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>
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
FSCSS:
npm install -g fscss@1.2.5
MIT. stack UI that opens with CSS.
Top comments (0)