32 CSS Floating Action Button Designs 16 / 32
Theme Toggle FAB
Floating light/dark mode toggle button with 4 style variants: circle, pill slider, square, and orbit ring — all synced to CSS variables.
The code
<div class="fb16">
<h1>Floating Theme Toggle</h1>
<p class="fb16-subtitle">Toggle light / dark mode — all 4 styles sync together</p>
<!-- Variant buttons -->
<div class="fb16-variants-row">
<!-- 1. Circle sun/moon -->
<div class="fb16-variant-col">
<button class="fb16-toggle-fab fb16-fab-circle" data-theme-toggle aria-label="Toggle theme">
<div class="fb16-fab-circle-inner">
<svg class="fb16-icon-sun" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="5"/>
<line x1="12" y1="1" x2="12" y2="3"/>
<line x1="12" y1="21" x2="12" y2="23"/>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/>
<line x1="1" y1="12" x2="3" y2="12"/>
<line x1="21" y1="12" x2="23" y2="12"/>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/>
</svg>
<svg class="fb16-icon-moon" viewBox="0 0 24 24">
<path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/>
</svg>
</div>
</button>
<div class="fb16-variant-label">Circle</div>
</div>
<!-- 2. Pill -->
<div class="fb16-variant-col">
<button class="fb16-toggle-fab fb16-fab-pill-toggle" data-theme-toggle aria-label="Toggle theme">
<div class="fb16-fab-pill-knob">
<svg class="fb16-knob-sun" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="5"/>
<line x1="12" y1="1" x2="12" y2="3"/>
<line x1="12" y1="21" x2="12" y2="23"/>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/>
<line x1="1" y1="12" x2="3" y2="12"/>
<line x1="21" y1="12" x2="23" y2="12"/>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/>
</svg>
<svg class="fb16-knob-moon" viewBox="0 0 24 24">
<path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/>
</svg>
</div>
</button>
<div class="fb16-variant-label">Pill Slider</div>
</div>
<!-- 3. Square emoji -->
<div class="fb16-variant-col">
<button class="fb16-toggle-fab fb16-fab-square-toggle" data-theme-toggle aria-label="Toggle theme">
<span class="fb16-fab-square-icon" id="fb16-squareIcon">☀️</span>
</button>
<div class="fb16-variant-label">Square</div>
</div>
<!-- 4. Orbit ring -->
<div class="fb16-variant-col">
<button class="fb16-toggle-fab fb16-fab-orbit" data-theme-toggle aria-label="Toggle theme">
<div class="fb16-fab-orbit-ring"></div>
<div class="fb16-fab-orbit-mask">
<svg class="fb16-orbit-sun" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="5"/>
<line x1="12" y1="1" x2="12" y2="3"/>
<line x1="12" y1="21" x2="12" y2="23"/>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/>
<line x1="1" y1="12" x2="3" y2="12"/>
<line x1="21" y1="12" x2="23" y2="12"/>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/>
</svg>
<svg class="fb16-orbit-moon" viewBox="0 0 24 24">
<path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/>
</svg>
</div>
</button>
<div class="fb16-variant-label">Orbit Ring</div>
</div>
</div>
<!-- Live preview card -->
<div class="fb16-preview-card">
<div class="fb16-preview-card-header">
<div class="fb16-avatar"></div>
<div class="fb16-card-meta">
<h3>Design System Preview</h3>
<p>See how your UI adapts to the active theme</p>
</div>
</div>
<div class="fb16-preview-body">
This card updates its background, text, borders, and accent colors instantly as you toggle. Every token is a CSS variable — a single <code style="font-family:monospace;font-size:.8em;background:var(--surface-2);padding:1px 5px;border-radius:3px;color:var(--accent)">data-theme</code> attribute on the root element switches the entire design.
</div>
<div class="fb16-preview-tags">
<span class="fb16-tag">Light Mode</span>
<span class="fb16-tag">Dark Mode</span>
<span class="fb16-tag">CSS Tokens</span>
<span class="fb16-tag">FAB Toggle</span>
</div>
<div class="fb16-theme-indicator">
<div class="fb16-mode-dot"></div>
<span id="fb16-modeLabel">Light Mode Active</span>
</div>
</div>
<!-- Fixed FAB (actual page toggle) -->
<div class="fb16-fab-fixed-wrap">
<button class="fb16-fab-fixed" id="fb16-fabFixed" data-theme-toggle aria-label="Toggle theme">
<div class="fb16-fab-fixed-burst"></div>
<svg class="fb16-icon-sun" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="5"/>
<line x1="12" y1="1" x2="12" y2="3"/>
<line x1="12" y1="21" x2="12" y2="23"/>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/>
<line x1="1" y1="12" x2="3" y2="12"/>
<line x1="21" y1="12" x2="23" y2="12"/>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/>
</svg>
<svg class="fb16-icon-moon" viewBox="0 0 24 24">
<path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/>
</svg>
</button>
</div>
</div> <div class="fb16">
<h1>Floating Theme Toggle</h1>
<p class="fb16-subtitle">Toggle light / dark mode — all 4 styles sync together</p>
<!-- Variant buttons -->
<div class="fb16-variants-row">
<!-- 1. Circle sun/moon -->
<div class="fb16-variant-col">
<button class="fb16-toggle-fab fb16-fab-circle" data-theme-toggle aria-label="Toggle theme">
<div class="fb16-fab-circle-inner">
<svg class="fb16-icon-sun" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="5"/>
<line x1="12" y1="1" x2="12" y2="3"/>
<line x1="12" y1="21" x2="12" y2="23"/>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/>
<line x1="1" y1="12" x2="3" y2="12"/>
<line x1="21" y1="12" x2="23" y2="12"/>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/>
</svg>
<svg class="fb16-icon-moon" viewBox="0 0 24 24">
<path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/>
</svg>
</div>
</button>
<div class="fb16-variant-label">Circle</div>
</div>
<!-- 2. Pill -->
<div class="fb16-variant-col">
<button class="fb16-toggle-fab fb16-fab-pill-toggle" data-theme-toggle aria-label="Toggle theme">
<div class="fb16-fab-pill-knob">
<svg class="fb16-knob-sun" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="5"/>
<line x1="12" y1="1" x2="12" y2="3"/>
<line x1="12" y1="21" x2="12" y2="23"/>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/>
<line x1="1" y1="12" x2="3" y2="12"/>
<line x1="21" y1="12" x2="23" y2="12"/>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/>
</svg>
<svg class="fb16-knob-moon" viewBox="0 0 24 24">
<path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/>
</svg>
</div>
</button>
<div class="fb16-variant-label">Pill Slider</div>
</div>
<!-- 3. Square emoji -->
<div class="fb16-variant-col">
<button class="fb16-toggle-fab fb16-fab-square-toggle" data-theme-toggle aria-label="Toggle theme">
<span class="fb16-fab-square-icon" id="fb16-squareIcon">☀️</span>
</button>
<div class="fb16-variant-label">Square</div>
</div>
<!-- 4. Orbit ring -->
<div class="fb16-variant-col">
<button class="fb16-toggle-fab fb16-fab-orbit" data-theme-toggle aria-label="Toggle theme">
<div class="fb16-fab-orbit-ring"></div>
<div class="fb16-fab-orbit-mask">
<svg class="fb16-orbit-sun" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="5"/>
<line x1="12" y1="1" x2="12" y2="3"/>
<line x1="12" y1="21" x2="12" y2="23"/>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/>
<line x1="1" y1="12" x2="3" y2="12"/>
<line x1="21" y1="12" x2="23" y2="12"/>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/>
</svg>
<svg class="fb16-orbit-moon" viewBox="0 0 24 24">
<path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/>
</svg>
</div>
</button>
<div class="fb16-variant-label">Orbit Ring</div>
</div>
</div>
<!-- Live preview card -->
<div class="fb16-preview-card">
<div class="fb16-preview-card-header">
<div class="fb16-avatar"></div>
<div class="fb16-card-meta">
<h3>Design System Preview</h3>
<p>See how your UI adapts to the active theme</p>
</div>
</div>
<div class="fb16-preview-body">
This card updates its background, text, borders, and accent colors instantly as you toggle. Every token is a CSS variable — a single <code style="font-family:monospace;font-size:.8em;background:var(--surface-2);padding:1px 5px;border-radius:3px;color:var(--accent)">data-theme</code> attribute on the root element switches the entire design.
</div>
<div class="fb16-preview-tags">
<span class="fb16-tag">Light Mode</span>
<span class="fb16-tag">Dark Mode</span>
<span class="fb16-tag">CSS Tokens</span>
<span class="fb16-tag">FAB Toggle</span>
</div>
<div class="fb16-theme-indicator">
<div class="fb16-mode-dot"></div>
<span id="fb16-modeLabel">Light Mode Active</span>
</div>
</div>
<!-- Fixed FAB (actual page toggle) -->
<div class="fb16-fab-fixed-wrap">
<button class="fb16-fab-fixed" id="fb16-fabFixed" data-theme-toggle aria-label="Toggle theme">
<div class="fb16-fab-fixed-burst"></div>
<svg class="fb16-icon-sun" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="5"/>
<line x1="12" y1="1" x2="12" y2="3"/>
<line x1="12" y1="21" x2="12" y2="23"/>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/>
<line x1="1" y1="12" x2="3" y2="12"/>
<line x1="21" y1="12" x2="23" y2="12"/>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/>
</svg>
<svg class="fb16-icon-moon" viewBox="0 0 24 24">
<path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/>
</svg>
</button>
</div>
</div>.fb16, .fb16 *, .fb16 *::before, .fb16 *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* ── Theme tokens ── */
:root {
--bg: #f5f7fa;
--surface: #ffffff;
--surface-2: #eef1f6;
--text: #1a202c;
--text-2: #718096;
--border: #e2e8f0;
--shadow: rgba(0,0,0,.08);
--accent: #4f46e5;
--accent-2: #a78bfa;
--fab-bg: #1a1a2e;
--fab-icon: #f6e05e;
--toggle-dur: .5s;
}
[data-theme="dark"] {
--bg: #0d0d14;
--surface: #14141f;
--surface-2: #1e1e2e;
--text: #e2e8f0;
--text-2: #64748b;
--border: #1e293b;
--shadow: rgba(0,0,0,.35);
--accent: #a78bfa;
--accent-2: #4f46e5;
--fab-bg: #fef9c3;
--fab-icon: #1a1a2e;
}
.fb16 { transition: background var(--toggle-dur) ease; }
.fb16 {
font-family: 'Plus Jakarta Sans', sans-serif;
background: var(--bg);
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 48px 24px 120px;
gap: 32px;
color: var(--text);
transition: background var(--toggle-dur) ease, color var(--toggle-dur) ease;
}
h1 {
font-size: 1.5rem;
font-weight: 800;
text-align: center;
color: var(--text);
transition: color var(--toggle-dur);
}
p.fb16-subtitle {
font-size: 0.85rem;
color: var(--text-2);
text-align: center;
margin-top: -24px;
transition: color var(--toggle-dur);
}
/* ── Variants row ── */
.fb16-variants-row {
display: flex;
gap: 32px;
flex-wrap: wrap;
justify-content: center;
align-items: flex-end;
}
.fb16-variant-col { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.fb16-variant-label {
font-size: 0.7rem;
font-weight: 600;
color: var(--text-2);
text-transform: uppercase;
letter-spacing: .06em;
transition: color var(--toggle-dur);
}
/* ── Toggle FAB shared ── */
.fb16-toggle-fab {
position: relative;
cursor: pointer;
border: none;
outline: none;
display: flex;
align-items: center;
justify-content: center;
transition: transform .2s cubic-bezier(.34,1.56,.64,1), box-shadow .2s;
}
.fb16-toggle-fab:hover { transform: scale(1.1); }
.fb16-toggle-fab:active { transform: scale(.93); }
/* Style 1: Circle with animated sun/moon swap */
.fb16-fab-circle {
width: 60px;
height: 60px;
border-radius: 50%;
background: var(--fab-bg);
box-shadow: 0 4px 18px var(--shadow);
transition: background var(--toggle-dur), box-shadow .2s, transform .2s;
overflow: hidden;
}
.fb16-fab-circle-inner {
position: relative;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.fb16-icon-sun, .fb16-icon-moon {
position: absolute;
width: 24px;
height: 24px;
stroke: var(--fab-icon);
fill: none;
stroke-width: 2.2;
stroke-linecap: round;
stroke-linejoin: round;
transition: opacity var(--toggle-dur), transform var(--toggle-dur), stroke var(--toggle-dur);
}
/* Light mode: show sun, hide moon */
.fb16-icon-sun { opacity: 1; transform: rotate(0deg) scale(1); }
.fb16-icon-moon { opacity: 0; transform: rotate(90deg) scale(.6); }
[data-theme="dark"] .fb16-icon-sun { opacity: 0; transform: rotate(-90deg) scale(.6); }
[data-theme="dark"] .fb16-icon-moon { opacity: 1; transform: rotate(0deg) scale(1); }
/* Style 2: Pill toggle (iOS-style slider) */
.fb16-fab-pill-toggle {
width: 64px;
height: 34px;
border-radius: 999px;
background: #e2e8f0;
position: relative;
padding: 0;
transition: background var(--toggle-dur);
box-shadow: inset 0 1px 3px rgba(0,0,0,.15);
}
[data-theme="dark"] .fb16-fab-pill-toggle { background: #7c3aed; }
.fb16-fab-pill-knob {
position: absolute;
top: 4px;
left: 4px;
width: 26px;
height: 26px;
border-radius: 50%;
background: #fff;
box-shadow: 0 2px 6px rgba(0,0,0,.2);
display: flex;
align-items: center;
justify-content: center;
transition: transform var(--toggle-dur) cubic-bezier(.34,1.3,.64,1);
}
[data-theme="dark"] .fb16-fab-pill-knob { transform: translateX(30px); }
.fb16-fab-pill-knob svg {
width: 14px; height: 14px;
fill: none;
stroke-width: 2;
stroke-linecap: round;
stroke-linejoin: round;
transition: stroke var(--toggle-dur), opacity var(--toggle-dur);
}
.fb16-knob-sun { stroke: #f59e0b; }
.fb16-knob-moon { stroke: #7c3aed; position: absolute; opacity: 0; }
[data-theme="dark"] .fb16-knob-sun { opacity: 0; }
[data-theme="dark"] .fb16-knob-moon { opacity: 1; }
/* Style 3: Square with morph icon */
.fb16-fab-square-toggle {
width: 56px;
height: 56px;
border-radius: 16px;
background: var(--surface);
border: 1.5px solid var(--border);
box-shadow: 0 2px 12px var(--shadow);
transition: background var(--toggle-dur), border-color var(--toggle-dur), box-shadow .2s, transform .2s;
}
.fb16-fab-square-icon {
font-size: 1.4rem;
line-height: 1;
display: block;
transition: transform var(--toggle-dur), filter var(--toggle-dur);
}
[data-theme="dark"] .fb16-fab-square-icon { transform: rotate(360deg); }
/* Style 4: Gradient orbit ring */
.fb16-fab-orbit {
width: 68px;
height: 68px;
border-radius: 50%;
background: var(--surface);
position: relative;
box-shadow: 0 4px 18px var(--shadow);
transition: background var(--toggle-dur), box-shadow .2s, transform .2s;
}
.fb16-fab-orbit-ring {
position: absolute;
inset: -4px;
border-radius: 50%;
background: conic-gradient(from 0deg, #f59e0b, #a78bfa, #38bdf8, #f59e0b);
z-index: -1;
transition: opacity var(--toggle-dur);
opacity: .7;
animation: fb16-orbit-spin 4s linear infinite;
}
[data-theme="dark"] .fb16-fab-orbit-ring { opacity: 1; }
@keyframes fb16-orbit-spin { to { transform: rotate(360deg); } }
.fb16-fab-orbit-mask {
position: absolute;
inset: 2px;
border-radius: 50%;
background: var(--surface);
display: flex;
align-items: center;
justify-content: center;
transition: background var(--toggle-dur);
}
.fb16-orbit-sun, .fb16-orbit-moon {
position: absolute;
width: 26px; height: 26px;
stroke: var(--text);
fill: none;
stroke-width: 2.2;
stroke-linecap: round;
stroke-linejoin: round;
transition: opacity var(--toggle-dur), transform var(--toggle-dur), stroke var(--toggle-dur);
}
.fb16-orbit-sun { opacity: 1; transform: scale(1); }
.fb16-orbit-moon { opacity: 0; transform: scale(.5) rotate(45deg); }
[data-theme="dark"] .fb16-orbit-sun { opacity: 0; transform: scale(.5) rotate(-45deg); }
[data-theme="dark"] .fb16-orbit-moon { opacity: 1; transform: scale(1) rotate(0deg); }
/* ── Live preview card ── */
.fb16-preview-card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 24px;
padding: 28px 32px;
max-width: 500px;
width: 100%;
box-shadow: 0 4px 24px var(--shadow);
transition: background var(--toggle-dur), border-color var(--toggle-dur), box-shadow var(--toggle-dur);
display: flex;
flex-direction: column;
gap: 16px;
}
.fb16-preview-card-header {
display: flex;
align-items: center;
gap: 12px;
}
.fb16-avatar {
width: 44px; height: 44px;
border-radius: 50%;
background: linear-gradient(135deg, var(--accent), var(--accent-2));
transition: background var(--toggle-dur);
}
.fb16-card-meta h3 {
font-size: 0.92rem;
font-weight: 700;
color: var(--text);
transition: color var(--toggle-dur);
}
.fb16-card-meta p {
font-size: 0.75rem;
color: var(--text-2);
transition: color var(--toggle-dur);
}
.fb16-preview-body {
font-size: 0.82rem;
color: var(--text-2);
line-height: 1.75;
transition: color var(--toggle-dur);
}
.fb16-preview-tags {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.fb16-tag {
padding: 4px 12px;
background: var(--surface-2);
border-radius: 999px;
font-size: 0.73rem;
font-weight: 600;
color: var(--accent);
transition: background var(--toggle-dur), color var(--toggle-dur);
}
.fb16-theme-indicator {
display: flex;
align-items: center;
gap: 6px;
font-size: 0.75rem;
font-weight: 700;
color: var(--text-2);
transition: color var(--toggle-dur);
}
.fb16-mode-dot {
width: 8px; height: 8px;
border-radius: 50%;
background: var(--accent);
transition: background var(--toggle-dur);
}
/* ── Fixed FAB (bottom-right) ── */
.fb16-fab-fixed-wrap {
position: fixed;
bottom: 28px;
right: 28px;
z-index: 200;
}
.fb16-fab-fixed {
width: 60px;
height: 60px;
border-radius: 50%;
background: var(--fab-bg);
border: none;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 6px 24px var(--shadow);
transition: background var(--toggle-dur), transform .2s cubic-bezier(.34,1.56,.64,1), box-shadow .2s;
outline: none;
overflow: hidden;
}
.fb16-fab-fixed:hover { transform: scale(1.1); }
.fb16-fab-fixed:active { transform: scale(.93); }
.fb16-fab-fixed .fb16-icon-sun { stroke: var(--fab-icon); }
.fb16-fab-fixed .fb16-icon-moon { stroke: var(--fab-icon); }
/* Burst overlay on toggle */
.fb16-fab-fixed-burst {
position: absolute;
inset: 0;
border-radius: 50%;
background: var(--fab-bg);
transform: scale(1);
opacity: 0;
pointer-events: none;
}
.fb16-fab-fixed.fb16-bursting .fb16-fab-fixed-burst {
animation: fb16-burst-out .5s ease-out forwards;
}
@keyframes fb16-burst-out {
0% { transform: scale(1); opacity: .5; }
100% { transform: scale(4); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
} .fb16, .fb16 *, .fb16 *::before, .fb16 *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* ── Theme tokens ── */
:root {
--bg: #f5f7fa;
--surface: #ffffff;
--surface-2: #eef1f6;
--text: #1a202c;
--text-2: #718096;
--border: #e2e8f0;
--shadow: rgba(0,0,0,.08);
--accent: #4f46e5;
--accent-2: #a78bfa;
--fab-bg: #1a1a2e;
--fab-icon: #f6e05e;
--toggle-dur: .5s;
}
[data-theme="dark"] {
--bg: #0d0d14;
--surface: #14141f;
--surface-2: #1e1e2e;
--text: #e2e8f0;
--text-2: #64748b;
--border: #1e293b;
--shadow: rgba(0,0,0,.35);
--accent: #a78bfa;
--accent-2: #4f46e5;
--fab-bg: #fef9c3;
--fab-icon: #1a1a2e;
}
.fb16 { transition: background var(--toggle-dur) ease; }
.fb16 {
font-family: 'Plus Jakarta Sans', sans-serif;
background: var(--bg);
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 48px 24px 120px;
gap: 32px;
color: var(--text);
transition: background var(--toggle-dur) ease, color var(--toggle-dur) ease;
}
h1 {
font-size: 1.5rem;
font-weight: 800;
text-align: center;
color: var(--text);
transition: color var(--toggle-dur);
}
p.fb16-subtitle {
font-size: 0.85rem;
color: var(--text-2);
text-align: center;
margin-top: -24px;
transition: color var(--toggle-dur);
}
/* ── Variants row ── */
.fb16-variants-row {
display: flex;
gap: 32px;
flex-wrap: wrap;
justify-content: center;
align-items: flex-end;
}
.fb16-variant-col { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.fb16-variant-label {
font-size: 0.7rem;
font-weight: 600;
color: var(--text-2);
text-transform: uppercase;
letter-spacing: .06em;
transition: color var(--toggle-dur);
}
/* ── Toggle FAB shared ── */
.fb16-toggle-fab {
position: relative;
cursor: pointer;
border: none;
outline: none;
display: flex;
align-items: center;
justify-content: center;
transition: transform .2s cubic-bezier(.34,1.56,.64,1), box-shadow .2s;
}
.fb16-toggle-fab:hover { transform: scale(1.1); }
.fb16-toggle-fab:active { transform: scale(.93); }
/* Style 1: Circle with animated sun/moon swap */
.fb16-fab-circle {
width: 60px;
height: 60px;
border-radius: 50%;
background: var(--fab-bg);
box-shadow: 0 4px 18px var(--shadow);
transition: background var(--toggle-dur), box-shadow .2s, transform .2s;
overflow: hidden;
}
.fb16-fab-circle-inner {
position: relative;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.fb16-icon-sun, .fb16-icon-moon {
position: absolute;
width: 24px;
height: 24px;
stroke: var(--fab-icon);
fill: none;
stroke-width: 2.2;
stroke-linecap: round;
stroke-linejoin: round;
transition: opacity var(--toggle-dur), transform var(--toggle-dur), stroke var(--toggle-dur);
}
/* Light mode: show sun, hide moon */
.fb16-icon-sun { opacity: 1; transform: rotate(0deg) scale(1); }
.fb16-icon-moon { opacity: 0; transform: rotate(90deg) scale(.6); }
[data-theme="dark"] .fb16-icon-sun { opacity: 0; transform: rotate(-90deg) scale(.6); }
[data-theme="dark"] .fb16-icon-moon { opacity: 1; transform: rotate(0deg) scale(1); }
/* Style 2: Pill toggle (iOS-style slider) */
.fb16-fab-pill-toggle {
width: 64px;
height: 34px;
border-radius: 999px;
background: #e2e8f0;
position: relative;
padding: 0;
transition: background var(--toggle-dur);
box-shadow: inset 0 1px 3px rgba(0,0,0,.15);
}
[data-theme="dark"] .fb16-fab-pill-toggle { background: #7c3aed; }
.fb16-fab-pill-knob {
position: absolute;
top: 4px;
left: 4px;
width: 26px;
height: 26px;
border-radius: 50%;
background: #fff;
box-shadow: 0 2px 6px rgba(0,0,0,.2);
display: flex;
align-items: center;
justify-content: center;
transition: transform var(--toggle-dur) cubic-bezier(.34,1.3,.64,1);
}
[data-theme="dark"] .fb16-fab-pill-knob { transform: translateX(30px); }
.fb16-fab-pill-knob svg {
width: 14px; height: 14px;
fill: none;
stroke-width: 2;
stroke-linecap: round;
stroke-linejoin: round;
transition: stroke var(--toggle-dur), opacity var(--toggle-dur);
}
.fb16-knob-sun { stroke: #f59e0b; }
.fb16-knob-moon { stroke: #7c3aed; position: absolute; opacity: 0; }
[data-theme="dark"] .fb16-knob-sun { opacity: 0; }
[data-theme="dark"] .fb16-knob-moon { opacity: 1; }
/* Style 3: Square with morph icon */
.fb16-fab-square-toggle {
width: 56px;
height: 56px;
border-radius: 16px;
background: var(--surface);
border: 1.5px solid var(--border);
box-shadow: 0 2px 12px var(--shadow);
transition: background var(--toggle-dur), border-color var(--toggle-dur), box-shadow .2s, transform .2s;
}
.fb16-fab-square-icon {
font-size: 1.4rem;
line-height: 1;
display: block;
transition: transform var(--toggle-dur), filter var(--toggle-dur);
}
[data-theme="dark"] .fb16-fab-square-icon { transform: rotate(360deg); }
/* Style 4: Gradient orbit ring */
.fb16-fab-orbit {
width: 68px;
height: 68px;
border-radius: 50%;
background: var(--surface);
position: relative;
box-shadow: 0 4px 18px var(--shadow);
transition: background var(--toggle-dur), box-shadow .2s, transform .2s;
}
.fb16-fab-orbit-ring {
position: absolute;
inset: -4px;
border-radius: 50%;
background: conic-gradient(from 0deg, #f59e0b, #a78bfa, #38bdf8, #f59e0b);
z-index: -1;
transition: opacity var(--toggle-dur);
opacity: .7;
animation: fb16-orbit-spin 4s linear infinite;
}
[data-theme="dark"] .fb16-fab-orbit-ring { opacity: 1; }
@keyframes fb16-orbit-spin { to { transform: rotate(360deg); } }
.fb16-fab-orbit-mask {
position: absolute;
inset: 2px;
border-radius: 50%;
background: var(--surface);
display: flex;
align-items: center;
justify-content: center;
transition: background var(--toggle-dur);
}
.fb16-orbit-sun, .fb16-orbit-moon {
position: absolute;
width: 26px; height: 26px;
stroke: var(--text);
fill: none;
stroke-width: 2.2;
stroke-linecap: round;
stroke-linejoin: round;
transition: opacity var(--toggle-dur), transform var(--toggle-dur), stroke var(--toggle-dur);
}
.fb16-orbit-sun { opacity: 1; transform: scale(1); }
.fb16-orbit-moon { opacity: 0; transform: scale(.5) rotate(45deg); }
[data-theme="dark"] .fb16-orbit-sun { opacity: 0; transform: scale(.5) rotate(-45deg); }
[data-theme="dark"] .fb16-orbit-moon { opacity: 1; transform: scale(1) rotate(0deg); }
/* ── Live preview card ── */
.fb16-preview-card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 24px;
padding: 28px 32px;
max-width: 500px;
width: 100%;
box-shadow: 0 4px 24px var(--shadow);
transition: background var(--toggle-dur), border-color var(--toggle-dur), box-shadow var(--toggle-dur);
display: flex;
flex-direction: column;
gap: 16px;
}
.fb16-preview-card-header {
display: flex;
align-items: center;
gap: 12px;
}
.fb16-avatar {
width: 44px; height: 44px;
border-radius: 50%;
background: linear-gradient(135deg, var(--accent), var(--accent-2));
transition: background var(--toggle-dur);
}
.fb16-card-meta h3 {
font-size: 0.92rem;
font-weight: 700;
color: var(--text);
transition: color var(--toggle-dur);
}
.fb16-card-meta p {
font-size: 0.75rem;
color: var(--text-2);
transition: color var(--toggle-dur);
}
.fb16-preview-body {
font-size: 0.82rem;
color: var(--text-2);
line-height: 1.75;
transition: color var(--toggle-dur);
}
.fb16-preview-tags {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.fb16-tag {
padding: 4px 12px;
background: var(--surface-2);
border-radius: 999px;
font-size: 0.73rem;
font-weight: 600;
color: var(--accent);
transition: background var(--toggle-dur), color var(--toggle-dur);
}
.fb16-theme-indicator {
display: flex;
align-items: center;
gap: 6px;
font-size: 0.75rem;
font-weight: 700;
color: var(--text-2);
transition: color var(--toggle-dur);
}
.fb16-mode-dot {
width: 8px; height: 8px;
border-radius: 50%;
background: var(--accent);
transition: background var(--toggle-dur);
}
/* ── Fixed FAB (bottom-right) ── */
.fb16-fab-fixed-wrap {
position: fixed;
bottom: 28px;
right: 28px;
z-index: 200;
}
.fb16-fab-fixed {
width: 60px;
height: 60px;
border-radius: 50%;
background: var(--fab-bg);
border: none;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 6px 24px var(--shadow);
transition: background var(--toggle-dur), transform .2s cubic-bezier(.34,1.56,.64,1), box-shadow .2s;
outline: none;
overflow: hidden;
}
.fb16-fab-fixed:hover { transform: scale(1.1); }
.fb16-fab-fixed:active { transform: scale(.93); }
.fb16-fab-fixed .fb16-icon-sun { stroke: var(--fab-icon); }
.fb16-fab-fixed .fb16-icon-moon { stroke: var(--fab-icon); }
/* Burst overlay on toggle */
.fb16-fab-fixed-burst {
position: absolute;
inset: 0;
border-radius: 50%;
background: var(--fab-bg);
transform: scale(1);
opacity: 0;
pointer-events: none;
}
.fb16-fab-fixed.fb16-bursting .fb16-fab-fixed-burst {
animation: fb16-burst-out .5s ease-out forwards;
}
@keyframes fb16-burst-out {
0% { transform: scale(1); opacity: .5; }
100% { transform: scale(4); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
}const root = document.documentElement;
const squareIcon = document.getElementById('fb16-squareIcon');
const modeLabel = document.getElementById('fb16-modeLabel');
const fabFixed = document.getElementById('fb16-fabFixed');
function applyTheme(theme) {
root.setAttribute('data-theme', theme);
squareIcon.textContent = theme === 'dark' ? '🌙' : '☀️';
modeLabel.textContent = theme === 'dark' ? 'Dark Mode Active' : 'Light Mode Active';
try { localStorage.setItem('fab-theme', theme); } catch(_) {}
}
function toggle() {
const next = root.getAttribute('data-theme') === 'dark' ? 'light' : 'dark';
applyTheme(next);
// Burst on the fixed FAB
fabFixed.classList.remove('fb16-bursting');
requestAnimationFrame(() => fabFixed.classList.add('fb16-bursting'));
}
// All toggle buttons trigger the same theme change
document.querySelectorAll('[data-theme-toggle]').forEach(btn => {
btn.addEventListener('click', toggle);
});
// Restore saved preference
try {
const saved = localStorage.getItem('fab-theme');
if (saved) applyTheme(saved);
} catch(_) {}
// Respect OS preference if no saved value
const osDark = window.matchMedia('(prefers-color-scheme: dark)');
try {
if (!localStorage.getItem('fab-theme') && osDark.matches) applyTheme('dark');
} catch(_) {
if (osDark.matches) applyTheme('dark');
} const root = document.documentElement;
const squareIcon = document.getElementById('fb16-squareIcon');
const modeLabel = document.getElementById('fb16-modeLabel');
const fabFixed = document.getElementById('fb16-fabFixed');
function applyTheme(theme) {
root.setAttribute('data-theme', theme);
squareIcon.textContent = theme === 'dark' ? '🌙' : '☀️';
modeLabel.textContent = theme === 'dark' ? 'Dark Mode Active' : 'Light Mode Active';
try { localStorage.setItem('fab-theme', theme); } catch(_) {}
}
function toggle() {
const next = root.getAttribute('data-theme') === 'dark' ? 'light' : 'dark';
applyTheme(next);
// Burst on the fixed FAB
fabFixed.classList.remove('fb16-bursting');
requestAnimationFrame(() => fabFixed.classList.add('fb16-bursting'));
}
// All toggle buttons trigger the same theme change
document.querySelectorAll('[data-theme-toggle]').forEach(btn => {
btn.addEventListener('click', toggle);
});
// Restore saved preference
try {
const saved = localStorage.getItem('fab-theme');
if (saved) applyTheme(saved);
} catch(_) {}
// Respect OS preference if no saved value
const osDark = window.matchMedia('(prefers-color-scheme: dark)');
try {
if (!localStorage.getItem('fab-theme') && osDark.matches) applyTheme('dark');
} catch(_) {
if (osDark.matches) applyTheme('dark');
}More from 32 CSS Floating Action Button Designs
Morph Expand FABSquircle FABGlassmorphism FABNeon Glow FABCompose + Tooltip FABClassic PlusSpeed DialPulse RingMorphing FABLabeled PillScroll to TopNeon Cyber
View the full collection →