webdevpuneet.com

Expanding FAB — Free HTML CSS JS Snippet

Expanding FAB · Buttons · Plain HTML, CSS & JS · Live preview

CategoryButtons

Copy & paste

Source Code

<div class="page">
  <div class="page-content">
    <p>Click the + button in the bottom-right to expand the action menu.</p>
  </div>

  <!-- Backdrop (outside fab-wrap so it never covers the action buttons) -->
  <div class="fab-backdrop" id="fab-backdrop" onclick="closeFab()"></div>

  <div class="fab-wrap" id="fab-wrap">
    <!-- Sub-actions (hidden by default) -->
    <div class="fab-actions" id="fab-actions">
      <div class="fab-action-item" style="--i:3">
        <span class="fab-tooltip">New document</span>
        <button class="fab-sub" onclick="fabAction('document')" aria-label="New document" style="background:#6366f1">
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>
        </button>
      </div>
      <div class="fab-action-item" style="--i:2">
        <span class="fab-tooltip">Upload file</span>
        <button class="fab-sub" onclick="fabAction('upload')" aria-label="Upload file" style="background:#0ea5e9">
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>
        </button>
      </div>
      <div class="fab-action-item" style="--i:1">
        <span class="fab-tooltip">Take photo</span>
        <button class="fab-sub" onclick="fabAction('photo')" aria-label="Take photo" style="background:#10b981">
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg>
        </button>
      </div>
    </div>

    <!-- Main FAB -->
    <button class="fab-main" id="fab-main" onclick="toggleFab()" aria-expanded="false" aria-label="Open actions">
      <svg class="fab-icon" id="fab-icon" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round">
        <line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/>
      </svg>
    </button>
  </div>

  <div class="fab-toast" id="fab-toast"></div>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Staggered sub-action entrance: CSS --i custom property × 0.05s delay per item
Transform: translateY(16px) scale(0.9) → 0 scale(1) slide-up entrance
+ rotates to × at 45deg: single icon, cubic-bezier spring curve
Blurred backdrop: backdrop-filter:blur(2px) + rgba(0,0,0,0.2) on open
Tooltip labels: .fab-tooltip shows left of each sub-action button
Sub-action colours: each button has independent background colour
Escape key close: document keydown listener
Toast feedback: slide-up confirmation for each triggered action

About this UI Snippet

Expanding FAB — Staggered Sub-Actions, Tooltip Labels, Rotate Icon & Blur Backdrop

Screenshot of the Expanding FAB snippet rendered live

A Floating Action Button (FAB) is the primary action button pattern in Material Design and most mobile-first web interfaces. The expanding FAB variant reveals multiple sub-actions when clicked — each secondary button slides up with a staggered delay, revealing contextual options without cluttering the main UI. For a radial-arc layout instead of a vertical stack, see the floating action button. This snippet provides a complete expanding FAB: a main button with a + icon that rotates to × on open, three sub-action buttons with staggered slide-up animations, tooltip labels, a blurred backdrop, and Escape key close.

The staggered animation

Each .fab-action-item has a CSS custom property --i (1, 2, or 3). In the .open state, transition-delay: calc((var(--i) - 1) × 0.05s) creates a staggered entrance: item 1 at 0ms, item 2 at 50ms, item 3 at 100ms. The transform goes from translateY(16px) scale(0.9) to translateY(0) scale(1). For the close animation, the delays reverse because transition-delay applies to the exit state too — the topmost item (--i: 3) closes first.

The + to × icon rotation

The main FAB icon uses transform: rotate(45deg) when .open is applied. The + character rotated 45° becomes a × shape — no icon swap needed. The cubic-bezier(0.34, 1.56, 0.64, 1) spring curve gives the rotation an overshoot bounce.

The blurred backdrop

When the FAB opens, a fixed-position backdrop covers the page. It fades from transparent to rgba(0,0,0,0.2) and applies backdrop-filter: blur(2px) — a subtle blur that visually separates the open FAB from the page content. Clicking the backdrop calls closeFab(). The pointer-events toggle prevents the backdrop from intercepting clicks when closed.

Sub-action tooltips

Each sub-action has a tooltip span that appears to the left of the button. The tooltips show on initial render but become visible only when the action item is visible (opacity: 1 in the open state). No JavaScript hover logic needed — the tooltip opacity is driven by the parent item's opacity.

Accessibility

The main FAB button has aria-expanded toggling with open state and aria-label="Open actions". Each sub-action button has aria-label describing its action. ESC key closes the FAB via document keydown listener.

Positioning and safe area handling

The FAB uses position: fixed; bottom: 28px; right: 28px. On iOS Safari, the home indicator area can overlap the FAB. Use CSS environment variables: bottom: calc(28px + env(safe-area-inset-bottom)) to push the FAB above the safe area. This is important for mobile web apps that users install as PWAs on their home screen.

Step by step

How to Use

  1. 1
    Click the + FAB button to expand sub-actionsThree sub-action buttons slide up with staggered timing. The + icon rotates to ×. A blurred backdrop appears. Click any sub-action to trigger its action, or click the × or backdrop to close.
  2. 2
    Update the sub-action icons and coloursEdit each .fab-sub button's inline style="background:#colour" and swap the inner SVG icon paths. Each sub-action gets its own colour — use brand colours or semantic colours (blue for upload, green for photo, etc.).
  3. 3
    Update the tooltip labelsEdit the .fab-tooltip span text inside each .fab-action-item div. Keep labels short (1-3 words) so they fit next to the button without wrapping.
  4. 4
    Add more sub-action buttonsDuplicate a .fab-action-item div, increment its --i value, update the button colour, icon, aria-label, and tooltip. Add the new action to the fabAction() switch statement.
  5. 5
    Change the FAB positionUpdate bottom and right on .fab-wrap to reposition. For top-right, change flex-direction to column (not column-reverse) so actions expand downward. For left-side FAB, set left: 28px and remove right.
  6. 6
    Export in your formatClick "HTML" for a standalone file, "JSX" for a React component using useState for open state, or "Tailwind" for a React + Tailwind CSS version.

Real-world uses

Common Use Cases

Mobile web app primary action button
The FAB is the standard mobile action pattern from Material Design — used in Google Drive, Gmail, and every Android app. Place it fixed bottom-right for the primary action users take most frequently in your app.
Dashboard create and compose actions
Use an expanding FAB in admin dashboards for create operations: new document, new task, invite user, upload file. Groups multiple "create" actions that would otherwise require separate toolbar buttons or a dropdown.
Content management and media library interfaces
CMS interfaces need quick access to create page, upload image, add widget, or record video. The FAB pattern groups these creation actions without taking space in the toolbar or content area.
Chat and messaging app compose actions
Messaging apps use expanding FABs for attach options: photo, file, location, contact. The backdrop dims the conversation thread while the user picks an attachment type. Close on Escape or backdrop click matches the expected mobile pattern.
Study CSS custom property stagger and backdrop-filter
The --i custom property technique for staggered animation delays demonstrates how CSS variables drive timing without JavaScript. The backdrop-filter: blur() pattern shows how to apply frosted glass blur behind a specific element rather than an entire overlay.
Social features and reaction picker buttons
Adapt the FAB as a social reaction picker (see the emoji reaction bar): main button shows a ❤ heart, sub-actions reveal 👍 👎 😂 😮 emojis. The tooltip shows the reaction name. Each sub-action fires a reaction API call on click.
Related: Load More Button
See the Load More Button for a related buttons pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

Each .fab-action-item has a style="--i:N" attribute where N is 1, 2, or 3. In CSS: .fab-actions.open .fab-action-item { transition-delay: calc((var(--i) - 1) * 0.05s); }. This gives item 1 a 0ms delay, item 2 a 50ms delay, and item 3 a 100ms delay. The items reveal from bottom to top (--i: 1 is nearest the FAB). For the close animation, remove the transition-delay rule from the .open state so all items close at the same speed.

Change .fab-main from a circle (border-radius: 50%; width/height: 56px) to a pill shape: border-radius: 28px; padding: 0 20px; width: auto; height: 56px. Add a text span inside: <button class="fab-main">+ <span>Create</span></button>. When open, the text can change to "Close" or disappear (display: none on .open) to make room for the × icon. Adjust the box-shadow accordingly.

Add padding-bottom: 100px to the main page content container so content does not hide behind the FAB at the bottom of scroll. Alternatively, make the FAB scrollable with the page instead of fixed: change position: fixed to position: sticky with appropriate margin. For critical content directly above the FAB, add bottom: 100px to that element.

Click "JSX" to download. Manage isOpen with useState(false). Pass isOpen to the main button, actions container, and backdrop via className. For sub-actions, use a CSS Module or Tailwind class that applies the transition-delay based on index: className={isOpen ? "fab-action-item open" : "fab-action-item"} with inline style={{ transitionDelay: isOpen ? index * 0.05 + "s" : "0s" }}.