Bundles save up to 25%. See every bundle

Code Boss
Dark

Full screen

What it does

A five-tab bottom bar for app-style sites, cut as a black obsidian slab with a machined groove along its foot. A polished chrome ball sits in a dimple under the selected tab. Tap another tab and the ball rolls there: it turns as it travels, the icons it passes under rise in a wave, and it arrives with a small overshoot before settling into the next dimple. As it lands, a thin ring ripples out along the groove, the warm light under the ball blooms once, and the icon fills in. Tap again mid-roll and the ball simply changes course. You can also grab the ball and drag it along the groove: it rolls under your finger, the icons near it rise, and when you let go it rolls on at your speed to the nearest dimple. A quick flick on the bar moves one tab.

Good for
Mobile-first web apps, PWAs, portfolio and product sites that want a tab bar people notice, music, reading and gaming apps.
How it works
One spring on a requestAnimationFrame loop moves the ball; the reflection on the ball turns with the distance travelled, one full turn per tab, so it rolls rather than slides and comes to rest level. Each frame measures how close the ball is to each icon and lifts the near ones. Dragging uses Pointer Events: the ball follows the pointer 1:1, resists past the ends, and on release hands the pointer's speed to the same spring, aimed where that speed would carry it. Works with mouse, pen and touch; vertical swipes still scroll the page. The ball, groove and dimples are CSS gradients and shadows drawn by the script, so your markup is just five buttons with icons.
How to use
Copy two files, paste the markup, call init(). It fires onChange with the tab's index and value.

Specs

Price
$5, one payment
Version
1.0.0
Code size
8.7 KB gzipped
Dependencies
None
Built with
HTML, CSS, JavaScript
Category
Navigation
Licence
Unlimited personal and client projects
In the zip
  • marble.css marble.jsthe component
  • index.htmla plain example page
  • README.mdsetup, CSS variables, icon guide, API, React notes
  • package.json vite.config.js npm install npm run dev
  • LICENSE.md

Use it in your project

  1. Copy marble.css and marble.js into your project.
  2. Add the markup from index.html (the block between the COMPONENT comments). Each tab is a button with an icon and a label; the groove, the dimples and the ball are drawn by the script.
  3. Start it:
import { init } from './marble.js';

const marble = init(document.querySelector('.marble'), {
  onChange: (index, value) => console.log(index, value),
});

Mark the starting tab with aria-selected="true". Each tab's data-value is passed to onChange.

### Your own icons

An icon is one 24 × 24 SVG with two paths that share a shape: .marble-fill (the solid shape, hidden until the tab is selected) and .marble-line (the outline, always drawn). Draw on a 24px grid with round caps; the stroke width is set in CSS. Any number of tabs works; the ball finds the centres itself.

Questions

What exactly do I get?

The full source, an example page and a README. No account, no framework.

Can I use it in client projects?

Yes, in unlimited projects. You can't resell or share the source itself.

Do I need React?

No. The README shows how to use it in React or Next.js.

Can I use my own icons?

Yes. Each icon is one SVG with an outline path and a matching fill path; the README explains the two classes. Any number of tabs works.

Is it keyboard accessible?

Yes. It is a tab list: Tab to focus, arrow keys, Home and End to change, with a visible focus ring. Keyboard moves crossfade the ball instead of rolling it, so stepping through tabs stays quick. The ball and the groove are hidden from screen readers.

Can I drag it?

Yes. Drag the ball (or drag anywhere on the bar) and let go, or flick the bar to move one tab. onChange fires once, on release. Pass drag: false to turn it off.

What about reduced motion?

The ball crossfades between dimples instead of rolling, the icons fill without the wave, and the finale is the dimple's glow fading in. Dragging still follows the finger, without the bounce.

Light and dark?

Both are designed: brushed aluminium with a steel ball and a steel-blue accent in the light theme; obsidian with a chrome ball and lamp-warm light in the dark one. With no theme set it follows the system.

Does it work on small screens?

Yes. Under 400px the labels hide, the bar fills the width and the ball keeps rolling. Tested at 320px.

What if it doesn't work for me?

If it doesn't work like the demo, you get a refund within 14 days.

Still have a question? Email us. The person who made it answers.

Your cart

Your cart is empty. Browse components

Full screen