34 CSS Floating Buttons
34 / 34

All 34 in 34 CSS Floating Buttons

  1. 01Material Design 3 Floating Action Button (FAB)
  2. 02iOS-Style Compose Floating Button
  3. 03WhatsApp Floating Message Button CSS
  4. 04Intercom / Drift Chat Bubble Floating Button
  5. 05Accessible WAI-ARIA Floating Action Button (WCAG 2.2)
  6. 06Extended FAB with Icon and Label (Material Design 3)
  7. 07Speed Dial Radial Menu FAB with Backdrop
  8. 08Pure CSS FAB Speed Dial (No JavaScript)
  9. 09Material Gradient Floating Action Button CSS
  10. 10Vertical and Horizontal Speed Dial FAB Menu CSS
  11. 11Morphing FAB Button That Expands to Pill CSS
  12. 12Scroll-to-Top Floating Button with SVG Progress Ring
  13. 13Floating Chat Widget FAB with Notification Panel
  14. 14Fan and Arc Radial Spread FAB Menu CSS
  15. 15Apple Squircle Superellipse Floating Button CSS
  16. 16Social Share Floating Button Cluster CSS
  17. 17Glassmorphism Floating Action Button with Backdrop Blur
  18. 18Cyberpunk Neon Glow Floating Button CSS
  19. 19Floating Compose Button with Tooltip on Hover CSS
  20. 20Draggable Floating Action Button with Corner Snap CSS
  21. 21Notification Bell Floating Button with Badge Counter
  22. 22Floating Cart Button with Live Badge Counter CSS
  23. 23Magnetic Cursor Follower Floating Button CSS
  24. 24Dark Mode Theme Toggle Floating Button CSS
  25. 25Classic Gradient Circle Plus FAB CSS
  26. 26Pulse Ring Attention-Getter Floating Button CSS
  27. 27Pill-Shaped FAB with Icon and Text Label CSS
  28. 28Neo-Brutalist Hard Shadow Floating Button CSS
  29. 29Floating Button with Loading Spinner State CSS
  30. 30Draggable Floating Button with 6-Dot Grip Handle CSS
  31. 31Voice Recording Microphone Floating Button CSS
  32. 32Aurora Gradient Drift Premium Floating Button CSS
  33. 33Quick Emoji Reply Reaction Floating Button CSS
  34. 34Modern Squircle Rounded Square FAB CSS
Pure CSSMIT licensed

Modern Squircle Rounded Square FAB CSS

The rounded-square FAB that replaced the circle in most 2025-onward interfaces, with the one rule that makes it work: radius is a constant fraction of size, not a fixed pixel value. 0.29 is the sweet spot — the same ratio app icons use. Includes a live comparison of five ratios and a hover that morphs radius rather than colour.

Live Demo
Try it

Nucleo: 44,000+ SVG icons in five families · All Icons Bundle $149

Nucleo · Affiliate link

Get the Nucleo bundle

The code

<section class="fb-34" aria-label="Modern squircle rounded square floating action button demo">
  <div class="fb-34__stage">
    <p class="fb-34__eyebrow">radius = size × ratio</p>
    <h2 class="fb-34__title">One ratio, every size</h2>
    <p class="fb-34__sub">Fixed pixel radii drift as buttons scale. Anchor the radius to a fraction of the size and a 40px control and a 96px hero read as the same shape.</p>
    <div class="fb-34__ladder">
      <div class="fb-34__cell"><button class="fb-34__fab" style="--fb-34-ratio:.5" type="button" aria-label="Ratio 0.5"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/></svg></button><span class="fb-34__cap">.50<i>circle</i></span></div>
      <div class="fb-34__cell"><button class="fb-34__fab fb-34__fab--hero" style="--fb-34-ratio:.29" type="button" aria-label="Ratio 0.29, recommended"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/></svg></button><span class="fb-34__cap">.29<i>squircle</i></span></div>
      <div class="fb-34__cell"><button class="fb-34__fab" style="--fb-34-ratio:.22" type="button" aria-label="Ratio 0.22"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/></svg></button><span class="fb-34__cap">.22<i>card</i></span></div>
      <div class="fb-34__cell"><button class="fb-34__fab" style="--fb-34-ratio:.12" type="button" aria-label="Ratio 0.12"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/></svg></button><span class="fb-34__cap">.12<i>chip</i></span></div>
      <div class="fb-34__cell"><button class="fb-34__fab" style="--fb-34-ratio:0" type="button" aria-label="Ratio zero"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/></svg></button><span class="fb-34__cap">.00<i>square</i></span></div>
    </div>
    <div class="fb-34__scale">
      <button class="fb-34__fab" style="--fb-34-size:40px" type="button" aria-label="40 pixel"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="2.6" stroke-linecap="round"/></svg></button>
      <button class="fb-34__fab" style="--fb-34-size:52px" type="button" aria-label="52 pixel"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"/></svg></button>
      <button class="fb-34__fab" style="--fb-34-size:64px" type="button" aria-label="64 pixel"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/></svg></button>
      <button class="fb-34__fab" style="--fb-34-size:80px" type="button" aria-label="80 pixel"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="2.3" stroke-linecap="round"/></svg></button>
      <button class="fb-34__fab" style="--fb-34-size:96px" type="button" aria-label="96 pixel"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"/></svg></button>
    </div>
    <p class="fb-34__caption">same 0.29 ratio · 40 → 96px · identical silhouette</p>
    <p class="fb-34__chip">hover morphs the ratio toward 0.5 in 280ms</p>
  </div>
</section>
.fb-34 {
  width: 100%;
  min-height: 100vh;
  min-height: 100svh;
  display: block;
  background: var(--fb-34-bg);
  --fb-34-bg: oklch(0.96 0.012 210);
  --fb-34-brand: oklch(0.52 0.13 215);
  --fb-34-brandDeep: oklch(0.38 0.11 218);
  --fb-34-ink: oklch(0.22 0.025 215);
  --fb-34-mut: oklch(0.53 0.015 215);
  --fb-34-size: 64px;
  --fb-34-ratio: .29;
  font-family: 'Segoe UI',system-ui,-apple-system,sans-serif;
  color: var(--fb-34-ink);
  display: grid;
  place-items: center;
  padding: clamp(20px,5vw,56px);
}

.fb-34 *,
.fb-34 *::before,
.fb-34 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.fb-34__stage {
  width: min(100%,62ch);
  display: grid;
  gap: clamp(16px,3vw,26px);
  justify-items: center;
  text-align: center;
}

.fb-34__eyebrow {
  font-family: ui-monospace,Menlo,Consolas,monospace;
  font-size: 11.5px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--fb-34-brand);
}

.fb-34__title {
  font-size: clamp(26px,4.6vw,44px);
  line-height: 1.05;
  letter-spacing: -.03em;
  font-weight: 700;
  text-wrap: balance;
}

.fb-34__sub {
  max-width: 52ch;
  font-size: clamp(13.5px,1.7vw,16.5px);
  line-height: 1.62;
  color: var(--fb-34-mut);
  text-wrap: pretty;
}

.fb-34__ladder {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(14px,4vw,30px);
  justify-content: center;
  align-items: flex-start;
  padding: 6px 0;
}

.fb-34__cell {
  display: grid;
  gap: 10px;
  justify-items: center;
}

.fb-34__cap {
  font-family: ui-monospace,Menlo,Consolas,monospace;
  font-size: 12px;
  font-weight: 650;
  display: grid;
  gap: 2px;
}

.fb-34__cap i {
  font-style: normal;
  font-size: 10px;
  font-weight: 400;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--fb-34-mut);
}

.fb-34__fab {
  display: grid;
  place-items: center;
  inline-size: var(--fb-34-size);
  block-size: var(--fb-34-size);
  border: 0;
  border-radius: calc(var(--fb-34-size) * var(--fb-34-ratio));
  cursor: pointer;
  color: oklch(0.99 0.01 215);
  background: linear-gradient(155deg,oklch(0.62 0.13 205),var(--fb-34-brandDeep));
  box-shadow: 0 12px 28px -12px oklch(0.38 0.11 218/.85),0 2px 5px oklch(0.28 0.05 218/.25);
  transition: border-radius .28s cubic-bezier(.2,.9,.3,1),transform .28s cubic-bezier(.2,1.25,.4,1),box-shadow .28s ease;
}

.fb-34__fab svg {
  width: calc(var(--fb-34-size) * .38);
  height: calc(var(--fb-34-size) * .38);
}

.fb-34__fab:hover {
  --fb-34-ratio: .5;
  transform: translateY(-3px);
  box-shadow: 0 18px 38px -12px oklch(0.38 0.11 218/.9);
}

.fb-34__fab:active {
  transform: scale(.95);
  --fb-34-ratio: .24;
}

.fb-34__fab:focus-visible {
  outline: 3px solid var(--fb-34-brandDeep);
  outline-offset: 4px;
}

.fb-34__fab--hero {
  background: linear-gradient(155deg,oklch(0.74 0.16 155),oklch(0.5 0.14 168));
  box-shadow: 0 14px 32px -12px oklch(0.5 0.14 168/.85),0 2px 5px oklch(0.28 0.05 168/.25);
  color: oklch(0.16 0.04 168);
}

.fb-34__fab--hero:hover {
  box-shadow: 0 20px 42px -12px oklch(0.5 0.14 168/.9);
}

@supports (corner-shape: squircle) {
  .fb-34__fab {
    corner-shape: squircle;
  }

  .fb-34__fab[style*=".5"] {
    corner-shape: round;
  }
}

.fb-34__scale {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(12px,3vw,22px);
  justify-content: center;
  align-items: center;
  padding: 10px 16px;
  border-radius: 24px;
  background: oklch(1 0 0/.7);
  border: 1px solid oklch(0.22 0.025 215/.08);
}

.fb-34__caption {
  font-family: ui-monospace,Menlo,Consolas,monospace;
  font-size: 11px;
  color: var(--fb-34-mut);
}

.fb-34__chip {
  font-family: ui-monospace,Menlo,Consolas,monospace;
  font-size: 11px;
  color: var(--fb-34-mut);
  padding: 8px 14px;
  border: 1px solid oklch(0.22 0.025 215/.14);
  border-radius: 99px;
}

@media (prefers-reduced-motion: reduce) {
  .fb-34__fab {
    transition: none;
  }
}
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Floating Button from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Modern Squircle Rounded Square FAB CSS
Source: https://codefronts.com/components/css-floating-buttons/fb16/

The rounded-square FAB that replaced the circle in most 2025-onward interfaces, with the one rule that makes it work: radius is a constant fraction of size, not a fixed pixel value. 0.29 is the sweet spot — the same ratio app icons use. Includes a live comparison of five ratios and a hover that morphs radius rather than colour.
## HTML
```html
<section class="fb-34" aria-label="Modern squircle rounded square floating action button demo">
  <div class="fb-34__stage">
    <p class="fb-34__eyebrow">radius = size × ratio</p>
    <h2 class="fb-34__title">One ratio, every size</h2>
    <p class="fb-34__sub">Fixed pixel radii drift as buttons scale. Anchor the radius to a fraction of the size and a 40px control and a 96px hero read as the same shape.</p>
    <div class="fb-34__ladder">
      <div class="fb-34__cell"><button class="fb-34__fab" style="--fb-34-ratio:.5" type="button" aria-label="Ratio 0.5"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/></svg></button><span class="fb-34__cap">.50<i>circle</i></span></div>
      <div class="fb-34__cell"><button class="fb-34__fab fb-34__fab--hero" style="--fb-34-ratio:.29" type="button" aria-label="Ratio 0.29, recommended"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/></svg></button><span class="fb-34__cap">.29<i>squircle</i></span></div>
      <div class="fb-34__cell"><button class="fb-34__fab" style="--fb-34-ratio:.22" type="button" aria-label="Ratio 0.22"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/></svg></button><span class="fb-34__cap">.22<i>card</i></span></div>
      <div class="fb-34__cell"><button class="fb-34__fab" style="--fb-34-ratio:.12" type="button" aria-label="Ratio 0.12"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/></svg></button><span class="fb-34__cap">.12<i>chip</i></span></div>
      <div class="fb-34__cell"><button class="fb-34__fab" style="--fb-34-ratio:0" type="button" aria-label="Ratio zero"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/></svg></button><span class="fb-34__cap">.00<i>square</i></span></div>
    </div>
    <div class="fb-34__scale">
      <button class="fb-34__fab" style="--fb-34-size:40px" type="button" aria-label="40 pixel"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="2.6" stroke-linecap="round"/></svg></button>
      <button class="fb-34__fab" style="--fb-34-size:52px" type="button" aria-label="52 pixel"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"/></svg></button>
      <button class="fb-34__fab" style="--fb-34-size:64px" type="button" aria-label="64 pixel"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/></svg></button>
      <button class="fb-34__fab" style="--fb-34-size:80px" type="button" aria-label="80 pixel"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="2.3" stroke-linecap="round"/></svg></button>
      <button class="fb-34__fab" style="--fb-34-size:96px" type="button" aria-label="96 pixel"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"/></svg></button>
    </div>
    <p class="fb-34__caption">same 0.29 ratio · 40 → 96px · identical silhouette</p>
    <p class="fb-34__chip">hover morphs the ratio toward 0.5 in 280ms</p>
  </div>
</section>
```
## CSS
```css
.fb-34 {
  width: 100%;
  min-height: 100vh;
  min-height: 100svh;
  display: block;
  background: var(--fb-34-bg);
  --fb-34-bg: oklch(0.96 0.012 210);
  --fb-34-brand: oklch(0.52 0.13 215);
  --fb-34-brandDeep: oklch(0.38 0.11 218);
  --fb-34-ink: oklch(0.22 0.025 215);
  --fb-34-mut: oklch(0.53 0.015 215);
  --fb-34-size: 64px;
  --fb-34-ratio: .29;
  font-family: 'Segoe UI',system-ui,-apple-system,sans-serif;
  color: var(--fb-34-ink);
  display: grid;
  place-items: center;
  padding: clamp(20px,5vw,56px);
}

.fb-34 *,
.fb-34 *::before,
.fb-34 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.fb-34__stage {
  width: min(100%,62ch);
  display: grid;
  gap: clamp(16px,3vw,26px);
  justify-items: center;
  text-align: center;
}

.fb-34__eyebrow {
  font-family: ui-monospace,Menlo,Consolas,monospace;
  font-size: 11.5px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--fb-34-brand);
}

.fb-34__title {
  font-size: clamp(26px,4.6vw,44px);
  line-height: 1.05;
  letter-spacing: -.03em;
  font-weight: 700;
  text-wrap: balance;
}

.fb-34__sub {
  max-width: 52ch;
  font-size: clamp(13.5px,1.7vw,16.5px);
  line-height: 1.62;
  color: var(--fb-34-mut);
  text-wrap: pretty;
}

.fb-34__ladder {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(14px,4vw,30px);
  justify-content: center;
  align-items: flex-start;
  padding: 6px 0;
}

.fb-34__cell {
  display: grid;
  gap: 10px;
  justify-items: center;
}

.fb-34__cap {
  font-family: ui-monospace,Menlo,Consolas,monospace;
  font-size: 12px;
  font-weight: 650;
  display: grid;
  gap: 2px;
}

.fb-34__cap i {
  font-style: normal;
  font-size: 10px;
  font-weight: 400;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--fb-34-mut);
}

.fb-34__fab {
  display: grid;
  place-items: center;
  inline-size: var(--fb-34-size);
  block-size: var(--fb-34-size);
  border: 0;
  border-radius: calc(var(--fb-34-size) * var(--fb-34-ratio));
  cursor: pointer;
  color: oklch(0.99 0.01 215);
  background: linear-gradient(155deg,oklch(0.62 0.13 205),var(--fb-34-brandDeep));
  box-shadow: 0 12px 28px -12px oklch(0.38 0.11 218/.85),0 2px 5px oklch(0.28 0.05 218/.25);
  transition: border-radius .28s cubic-bezier(.2,.9,.3,1),transform .28s cubic-bezier(.2,1.25,.4,1),box-shadow .28s ease;
}

.fb-34__fab svg {
  width: calc(var(--fb-34-size) * .38);
  height: calc(var(--fb-34-size) * .38);
}

.fb-34__fab:hover {
  --fb-34-ratio: .5;
  transform: translateY(-3px);
  box-shadow: 0 18px 38px -12px oklch(0.38 0.11 218/.9);
}

.fb-34__fab:active {
  transform: scale(.95);
  --fb-34-ratio: .24;
}

.fb-34__fab:focus-visible {
  outline: 3px solid var(--fb-34-brandDeep);
  outline-offset: 4px;
}

.fb-34__fab--hero {
  background: linear-gradient(155deg,oklch(0.74 0.16 155),oklch(0.5 0.14 168));
  box-shadow: 0 14px 32px -12px oklch(0.5 0.14 168/.85),0 2px 5px oklch(0.28 0.05 168/.25);
  color: oklch(0.16 0.04 168);
}

.fb-34__fab--hero:hover {
  box-shadow: 0 20px 42px -12px oklch(0.5 0.14 168/.9);
}

@supports (corner-shape: squircle) {
  .fb-34__fab {
    corner-shape: squircle;
  }

  .fb-34__fab[style*=".5"] {
    corner-shape: round;
  }
}

.fb-34__scale {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(12px,3vw,22px);
  justify-content: center;
  align-items: center;
  padding: 10px 16px;
  border-radius: 24px;
  background: oklch(1 0 0/.7);
  border: 1px solid oklch(0.22 0.025 215/.08);
}

.fb-34__caption {
  font-family: ui-monospace,Menlo,Consolas,monospace;
  font-size: 11px;
  color: var(--fb-34-mut);
}

.fb-34__chip {
  font-family: ui-monospace,Menlo,Consolas,monospace;
  font-size: 11px;
  color: var(--fb-34-mut);
  padding: 8px 14px;
  border: 1px solid oklch(0.22 0.025 215/.14);
  border-radius: 99px;
}

@media (prefers-reduced-motion: reduce) {
  .fb-34__fab {
    transition: none;
  }
}
```

How this works

The whole system is one ratio token:

.fab{ --size:64px; --ratio:.29;
      inline-size:var(--size); block-size:var(--size);
      border-radius:calc(var(--size) * var(--ratio)); }

Fixed pixel radii break at scale: 16px on a 40px button is a soft square, on a 96px button it is nearly sharp. Anchoring to a ratio keeps the silhouette identical at every size, which is what lets a 40px toolbar button and a 96px hero FAB read as the same component.

The ratios worth knowing: 0.5 is a circle, 0.29 is the app-icon squircle, 0.22 reads as a card, 0.12 as a chip, 0 as brutalist. Below about 0.1 the corner stops doing any work.

Because the radius is a calc from a custom property, it interpolates — hovering morphs from squircle toward circle in 280ms, and the transition is smooth rather than stepped. Pair it with corner-shape:squircle where supported for a truly continuous curve.

Make it yours

  • Design-system token: expose the ratio as a global (--radius-ratio) and every rounded element in the product stays in family.
  • Directional radius: a larger radius on the corner nearest the screen edge makes a docked button feel attached to it.
  • Press morph: shrink the ratio slightly on :active so the button squares up as it is pressed — subtle, physical.
  • Nested radius: an inner element's radius should be the parent's minus the padding, or the curves will not sit concentric.

Gotchas — read before shipping

  • Never mix fixed and ratio radii in one component set; the mismatch is subtle at one size and obvious across three.
  • border-radius percentages behave differently from calc ratios — 29% of a non-square box gives an ellipse, not a squircle.
  • Nested rounded elements need computed inner radii. An inner radius equal to the outer one looks visibly wrong at the corners.
  • At very small sizes, ratio radii round down to sub-pixel values and the corners look inconsistent between browsers. Below 32px, set a floor.

Browser support

ChromeSafariFirefoxEdge
114+17.5+121+114+

Floor set by oklch(), text-wrap as this demo is written. The core technique itself goes back further — Chrome 111+.

calc() with custom properties in border-radius works everywhere modern. The optional corner-shape:squircle enhancement is Chrome 139+ and Safari 26+, wrapped in @supports.

Search CodeFronts

Loading…