Floating action button
Category: Buttons · Tags: fab, floating, create, primary-action, mobile
Notes
- Call the venue about Friday's room booking
- Draft the agenda for the planning meeting
- Send slides to the design team
How to use it
Use for the one primary creation action of a mobile-style screen or panel, such as adding a note to a list. Use at most one per view, and never for secondary or destructive actions; on wide layouts a normal labelled button in the header is usually clearer. The button is pinned to the corner of .dcl-fab, not of the page -- make that wrapper your scrolling panel, or switch it to position: fixed if you really want it on the viewport -- and change the aria-label and the click handler to your own create action.
Accessibility
The round button is a native <button> whose icon is aria-hidden and whose accessible name comes from aria-label="New note", so it is announced and activated like any button with Tab, Enter or Space; it shows a 3px focus outline and is 3.5rem (56px) across. It is absolutely positioned inside its own position: relative container, and the list keeps enough bottom padding that the button never covers the last item. Adding a note writes "Note added." into a role="status" line. Text is #0f172a on #ffffff (17.85:1), list notes are #475569 on #ffffff (7.58:1), and the icon is #ffffff on #1d4ed8 (6.70:1) and on the #1e40af hover (8.72:1).
Source (copy-ready)
<section class="dcl-fab" aria-labelledby="dcl-fab-title">
<h3 class="dcl-fab__title" id="dcl-fab-title">Notes</h3>
<ul class="dcl-fab__list">
<li class="dcl-fab__item">Call the venue about Friday's room booking</li>
<li class="dcl-fab__item">Draft the agenda for the planning meeting</li>
<li class="dcl-fab__item">Send slides to the design team</li>
</ul>
<p class="dcl-fab__status" role="status"></p>
<button type="button" class="dcl-fab__button" aria-label="New note">
<svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false"><path d="M12 5v14M5 12h14" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"/></svg>
</button>
</section>
<style>
.dcl-fab { position: relative; max-width: 22rem; min-height: 15rem; padding: 1rem 1rem 5rem; border: 1px solid #cbd5e1; border-radius: 0.75rem; font: inherit; color: #0f172a; background-color: #ffffff; }
.dcl-fab__title { margin: 0 0 0.5rem; font-size: 1.1rem; color: #0f172a; background-color: #ffffff; }
.dcl-fab__list { margin: 0; padding: 0; list-style: none; }
.dcl-fab__item { padding: 0.6rem 0; border-bottom: 1px solid #e2e8f0; overflow-wrap: anywhere; color: #475569; background-color: #ffffff; }
.dcl-fab__status { min-height: 1.5em; margin: 0.5rem 0 0; color: #0f172a; background-color: #ffffff; }
.dcl-fab__button { position: absolute; right: 1rem; bottom: 1rem; display: inline-flex; align-items: center; justify-content: center; width: 3.5rem; height: 3.5rem; padding: 0; border: none; border-radius: 50%; cursor: pointer; box-shadow: 0 2px 6px #94a3b8; color: #ffffff; background-color: #1d4ed8; }
.dcl-fab__button:hover { color: #ffffff; background-color: #1e40af; }
.dcl-fab__button:focus-visible { outline: 3px solid #0f172a; outline-offset: 3px; }
</style>
<script>
(function () {
document.querySelectorAll(".dcl-fab").forEach(function (root) {
if (root.dataset.dclBound) { return; }
root.dataset.dclBound = "true";
var button = root.querySelector(".dcl-fab__button");
var list = root.querySelector(".dcl-fab__list");
var status = root.querySelector(".dcl-fab__status");
var count = 0;
if (!button || !list) { return; }
button.addEventListener("click", function () {
count += 1;
var item = document.createElement("li");
item.className = "dcl-fab__item";
item.textContent = "Untitled note " + count;
list.appendChild(item);
if (status) { status.textContent = "Note added."; }
});
});
})();
</script>
Was this useful? Send feedback.