Monsoon v0.2.0
Made by Alexandre Kohler Star

Actions and feedback

Floating action button

A floating action button whose speed dial opens on hover or keyboard focus, with no script.

Actions and feedback9 classesNo JavaScriptLight and dark

Example

Full

Classes

9 classes. Click a name to copy it. Utilities on the same element always win over component defaults, so any of them can be adjusted with plain utility classes.

ClassTypeWhat it does
Base Base class of the floating action button. On a <div> in the example. Sets fixed position, stacking order, offsets, flex display, alignment and gap.
CSS
:is(.fab:focus-within, .fab:hover, .fab-open) :where(.fab-trigger > svg) {
  rotate: 45deg;
}

:is(.fab:focus-within, .fab:hover, .fab-open) > .fab-actions {
  opacity: 1;
  visibility: visible;
  translate: 0 0;
  transition-delay: 0s;
}
Part Part of the floating action button. On a <button> in the example. Sets shadow.
CSS
.fab-trigger {
  box-shadow: 0 10px 24px -8px color-mix(in oklab, var(--tone, var(--primary)) 60%, transparent), var(--m-shadow-md);
}

:where(.fab-trigger > svg) {
  transition: rotate var(--m-duration) var(--m-ease);
}
Part Part of the floating action button. On a <div> in the example. Sets flex display, alignment, gap, opacity, transform and transition.
CSS
@media (prefers-reduced-motion: reduce) {
  .btn, .copy-btn, .segmented-item, .toggle-group-item, .chip, .chip-remove, .fab-actions, .swap > .swap-on, .swap > .swap-off, .tooltip::after, .tooltip::before, .dismiss > :where(summary) {
    transition: none;
  }
}

.fab-actions {
  display: flex;
  flex-direction: column-reverse;
  align-items: inherit;
  gap: 0.625rem;
  opacity: 0;
  visibility: hidden;
  translate: 0 0.5rem;
  transition: opacity var(--m-duration) var(--m-ease), translate var(--m-duration) var(--m-ease), visibility 0s linear var(--m-duration);
}
Part Part of the floating action button. On a <div> in the example. Sets flex display, alignment and gap.
CSS
.fab-action {
  display: flex;
  align-items: center;
  gap: 0.625rem;
}

.fab-start .fab-action {
  flex-direction: row-reverse;
}
Part Part of the floating action button. On a <span> in the example. Sets padding, border, corner radius, background, text color and shadow, and 4 custom properties.
CSS
@supports not (color: oklch(from red l c h)) {
  .btn,
  .alert,
  .callout,
  .banner,
  .badge,
  .chip,
  .tag,
  .notification,
  .toggle-group-item,
  .fab-label {
    --tone-ink: var(--tone);
  }
}

.btn,
.alert,
.callout,
.banner,
.badge,
.chip,
.tag,
.notification,
.toggle-group-item,
.fab-label,
.progress,
.radial-progress {
  --tone-tint: var(--tone);
  --tone-ink: oklch(from var(--tone) calc(min(l, 0.5) * (1 - var(--mode)) + max(l, 0.8) * var(--mode)) min(c, 0.2) h);
}
Modifier Modifier, combined with the fab class. On a <div> in the example. Sets offsets and alignment.
CSS
.fab-start .fab-action {
  flex-direction: row-reverse;
}

.fab-start {
  inset-inline-start: 1.5rem;
  inset-inline-end: auto;
  align-items: flex-start;
}
Modifier Modifier, combined with the fab class. Not used in the example above. Sets offsets, transform and alignment.
CSS
.fab-contained:not(.fab-start, .fab-center) {
  inset-inline-end: 1rem;
}

.fab-center {
  inset-inline-start: 50%;
  inset-inline-end: auto;
  translate: -50% 0;
  align-items: center;
}
Modifier Modifier, combined with the fab class. On a <div> in the example. Sets absolute position and offsets.
CSS
.fab-contained.fab-start {
  inset-inline-start: 1rem;
}

.fab-contained {
  position: absolute;
  inset-block-end: 1rem;
}
Modifier Modifier, combined with the fab class. On a <div> in the example. Sets transform, opacity and transition.
CSS
:is(.fab:focus-within, .fab:hover, .fab-open) :where(.fab-trigger > svg) {
  rotate: 45deg;
}

:is(.fab:focus-within, .fab:hover, .fab-open) > .fab-actions {
  opacity: 1;
  visibility: visible;
  translate: 0 0;
  transition-delay: 0s;
}

Usage

Components ship inside the same stylesheet as the utilities. There is nothing else to install and no script to load: link Monsoon and write the markup.

index.html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/monsooncss">

<!-- Floating action button: start from the base class, then add modifiers -->
<div class="relative h-64 rounded-xl border bg-muted overflow-hidden">
  <div class="fab fab-contained">
    <button class="btn btn-circle btn-lg fab-trigger" aria-label="Create"><svg class="size-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg></button>
    <div class="fab-actions">
      <div class="fab-action"><span class="fab-label">New note</span><button class="btn btn-circle btn-soft" aria-label="New note"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 20h9"/><path d="M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4z"/></svg></button></div>
      <div class="fab-action"><span class="fab-label">Upload image</span><button class="btn btn-circle btn-soft" aria-label="Upload image"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-3.1-3.1a2 2 0 0 0-2.8 0L6 21"/></svg></button></div>
      <div class="fab-action"><span class="fab-label">Share</span><button class="btn btn-circle btn-soft" aria-label="Share"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><path d="m8.6 13.5 6.8 4M15.4 6.5l-6.8 4"/></svg></button></div>
    </div>
  </div>
  <div class="fab fab-contained fab-start fab-open">
    <button class="btn btn-circle btn-neutral fab-trigger" aria-label="Menu"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg></button>
    <div class="fab-actions">
      <div class="fab-action"><span class="fab-label">Always open</span><button class="btn btn-circle btn-sm btn-outline btn-neutral" aria-label="Mail"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="m22 7-10 6L2 7"/></svg></button></div>
    </div>
<!-- the full example is in the Code tab above -->

Theme it with --seed on any ancestor, for example style="--seed: #0d9488", and force a scheme with class="dark" or class="light" on a wrapper.

Accessibility

  • Use button for actions and a for navigation. Icon only buttons need an aria-label; decorative icons carry aria-hidden="true".
  • Every interactive part shows a visible focus ring with :focus-visible, and tone colors pair with -foreground tokens that keep text at 4.5:1 or better in light and dark mode.

No recent searches

Try , , or .

Recent

Loading the search index

No results for ""

Check the spelling, or search a class name such as px-4.