Floating Dock — Free HTML CSS JS macOS Dock Snippet

Floating Dock · Navigation · Plain HTML, CSS & JS · Live preview

Share & Support

What's included

Features

Gaussian proximity magnification
Scale uses 1 + (MAX_SCALE - 1) * t² where t = 1 - dist/SPREAD — a quadratic falloff that mirrors the physical feel of the macOS Dock precisely.
CSS custom property animation
--scale and --ty are set per-icon via JS and consumed by the CSS transform. The CSS transition interpolates between values, eliminating the need for a JS animation loop.
Click bounce via Web Animations API
element.animate() fires a 3-keyframe bounce on click — scale up 15%, lift 8px, return — without requiring class toggles or event listener cleanup.
Glassmorphism container
backdrop-filter: blur(20px) + rgba background + subtle white border creates the frosted-glass dock shelf, matching the macOS aesthetic.
Hover label tooltip
Each icon shows a label tooltip above it on hover — CSS opacity transition, no JS required. Works with keyboard focus too.
Vertical lift effect
Magnified icons translate upward (translateY negative), so the bottom edges stay aligned to the dock shelf while the tops extend upward — exactly like macOS.
Keyboard accessible
Each dock item has tabindex="0" and a keydown handler for Enter/Space — the bounce fires on keyboard activation too.
Tunable parameters
MAX_SCALE (default 1.8) and SPREAD (default 120px) are top-of-file constants — one line to change the effect intensity or reach.

About this UI Snippet

Floating Dock — macOS Magnification Effect, Gaussian Proximity Scale & CSS Custom Property Animation

Screenshot of the Floating Dock snippet rendered live

The macOS Dock's icon magnification is one of the most studied interaction effects in UI design — smooth, responsive, and physically intuitive. This snippet reproduces it in pure HTML, CSS, and JavaScript: a glassmorphism toolbar with coloured icon tiles that scale up toward the cursor using a Gaussian proximity formula, lift off the shelf, and bounce on click — with CSS custom properties driving every transform frame.

The macOS Dock icon magnification effect is one of the most recognisable and studied animations in software UI. It demonstrates a core principle: interactions should feel physical, as though the cursor is pushing objects rather than toggling states. This snippet reproduces the full effect — proximity-based magnification, smooth falloff, vertical lift, click bounce, label tooltip, glassmorphism container, and separator line — in pure HTML, CSS, and vanilla JavaScript with zero dependencies.

The magnification math: Gaussian proximity formula

The core of the effect is a distance-based scale calculation. When the cursor is at pixel X, for each dock icon the code computes dist = Math.abs(mouseX - iconCenter). It then computes t = 1 - dist / SPREAD — a linear falloff where t = 1 at the cursor and t = 0 at distance = SPREAD (120px by default). The scale is computed as 1 + (MAX_SCALE - 1) * t * t — squaring t makes the falloff nonlinear (Gaussian-like), so nearby icons grow large quickly while distant icons barely move. The vertical lift is LIFT * t * t — a negative value (−12px) that moves icons upward proportionally to their scale. Both are written to CSS custom properties (--scale and --ty) on each item element so the CSS transform expression reads them: transform: scale(var(--scale)) translateY(var(--ty)).

CSS custom properties as per-element animation state

Writing magnification data to CSS custom properties on individual elements (rather than inline transforms) has an important advantage: the CSS transition declaration on .icon-bg animates between the old and new custom property values automatically. When the cursor moves and --scale updates, the transition interpolates from the previous scale to the new one — giving the spring-ease feel without any JavaScript animation loop. The transition uses cubic-bezier(.34,1.56,.64,1), the same spring-overshoot easing used throughout the snippet collection, which gives the icons a slight bounce when they reach their peak.

The click bounce using Web Animations API

Clicking an icon triggers a programmatic keyframe animation using the Web Animations API (element.animate()). The three keyframes scale the icon up 15% and lift it an extra 8px before returning to the base value. The easing is the same spring cubic-bezier. Using element.animate() for the click bounce is preferable to adding/removing a CSS class because: it doesn't require a transitionend or animationend cleanup listener, it composes with the existing CSS transition without conflict, and it fires once and cleans itself up.

Glassmorphism container

The dock container uses background: rgba(255,255,255,0.08), backdrop-filter: blur(20px), and a 1px border: rgba(255,255,255,0.12) — the standard glassmorphism recipe. Icons are coloured <div> tiles with border-radius: 14px and individual linear-gradient backgrounds, matching the macOS icon aesthetic.

Customising the dock

Change MAX_SCALE (default 1.8) and SPREAD (default 120px) to tune magnification intensity and spread. Increase MAX_SCALE to 2.2 for a more dramatic effect. Change the icon SVGs and gradient colours to match your app. Add or remove .dock-item divs — the layout is display:flex; align-items:flex-end so all icons naturally bottom-align and taller magnified icons push upward rather than downward. Pair with a hamburger nav for a full navigation system.

Step by step

How to Use

  1. 1
    Load the snippetPaste the HTML, CSS, and JS into your page. A glassmorphism dock bar appears at the bottom with five colour-coded app icons and a trash icon after a separator.
  2. 2
    Move the cursor slowly over the dockIcons near the cursor magnify smoothly up to 1.8× their size and lift slightly off the shelf. Icons further away scale proportionally less — the falloff is Gaussian, not linear.
  3. 3
    Move across the full dockAs the cursor moves, the magnification wave follows — each icon grows and shrinks based on its real-time distance from the cursor, just like the macOS Dock.
  4. 4
    Click any iconThe clicked icon bounces up 8px and scales to 115% before springing back to its current magnified size, providing satisfying click feedback.
  5. 5
    Hover to see the labelA small tooltip label appears above each icon on hover — "Finder", "Terminal", etc. It fades in with a CSS opacity transition.
  6. 6
    Customise icons and coloursSwap each .icon-bg gradient and SVG to match your app's icons. Adjust MAX_SCALE and SPREAD in the JS to tune the magnification intensity and reach.

Real-world uses

Common Use Cases

Application launcher bars
Provide a floating toolbar at the bottom of a web app with quick-launch icons for core sections, matching desktop OS conventions for muscle memory.
Portfolio site navigation
Replace a traditional navbar with a floating dock for a distinctive layout. Each icon links to a portfolio section — About, Projects, Blog, Contact.
Tool palette in editors
Creative tools (image editors, diagramming apps, code playgrounds) can use a dock for formatting tools, with the magnification making dense icon bars easier to target.
Interactive demos and showcases
Use the dock as a visual centerpiece on a landing page to demonstrate app features. Each icon reveals a feature panel when clicked.
Tab bar on tablet layouts
On tablet-sized viewports, a floating dock replaces a sidebar nav — familiar to iPad users and more space-efficient than a full sidebar. For phone layouts a fixed bottom nav is the more conventional pattern.
Shortcut bars in SaaS dashboards
Provide a persistent floating action bar for frequently used operations. Pair with a command palette for keyboard power users.

Got questions?

Frequently Asked Questions

Increase MAX_SCALE at the top of the JS (default 1.8). Try 2.2 for a more dramatic macOS-like effect or 1.4 for a subtle zoom. Increase SPREAD (default 120px) to make the magnification wave wider — more icons are affected as the cursor approaches.

Duplicate a .dock-item div in the HTML. Set the data-label attribute for the tooltip text, change the background gradient on .icon-bg, and swap the SVG icon. The JS reads all .dock-item elements automatically.

Setting an inline style.transform directly would conflict with the CSS transition declaration — the browser would skip the transition because the old value is the same inline style that was just overwritten. Writing to CSS custom properties (--scale, --ty) consumed by the CSS transform expression lets the transition engine compare the old and new custom property values and interpolate between them.

Yes. Use the JSX, Vue, Angular, or Tailwind export buttons on this page. In React, attach the mousemove and mouseleave handlers to the dock container via a ref in useEffect with cleanup. Keep the per-icon --scale values in a useRef (not useState) to avoid re-renders on every mouse move — write directly to the DOM element's CSS custom properties for smooth 60fps updates. In Vue, use a template ref and onMounted; in Angular, use @ViewChild and ngAfterViewInit.

Set opacity: 0; transform: translateY(100%) on .dock-wrap by default, then add a :hover or a class that sets opacity: 1; transform: translateY(0). Trigger the class on body:hover or bind it to a bottom-of-screen IntersectionObserver trigger.