Buttons
tier 2 — classes.btn is the base; every variant is one extra class. A panel's primary call to
action is always a filled button in its semantic colour.
| Class | Use for |
|---|---|
.btn-primary | The neutral primary action |
.btn-go | Sends something outward — approve, apply, send, reroute |
.btn-warn-solid | Changes who is in control — accept and take over |
.btn-warn | The same action as a secondary, beside a green primary |
.btn-danger | Destructive |
_content/DR.Simple_UI/lib/remixicon/remixicon.css and use ri-* classes on
an <i>. Browse all 3,245 at remixicon.com.
Variants
The full set, all at the same height.
<button class="btn">Neutral</button>
<button class="btn btn-primary">Primary</button>
<button class="btn btn-go"><i class="ri-check-line"></i> Approve & send</button>
<button class="btn btn-warn-solid"><i class="ri-user-shared-line"></i> Accept & take over</button>
<button class="btn btn-warn">Take over</button>
<button class="btn btn-danger"><i class="ri-delete-bin-line"></i> Delete</button>
<button class="btn" disabled>Disabled</button>
Three sizes
.btn-sm, the default, and .btn-lg. Every control that can share a row
takes the same three heights — 28px, 36px and 44px — so a button, a link, an
icon button, a field and a chip line up at every size.
A badge does not: it is a label rather than a target, so it has its own scale that lines up with text instead.
<div class="dr-col dr-gap-2">
<div class="dr-row-wrap">
<button class="btn btn-sm">Small</button>
<button class="btn btn-sm btn-primary"><i class="ri-check-line"></i> Small</button>
<button class="btn btn-sm btn-icon" aria-label="Small icon"><i class="ri-refresh-line"></i></button>
<span class="chip"><span class="chip-label">Small chip</span></span>
<a class="btn btn-sm" href="#sizes">Small link</a>
</div>
<div class="dr-row-wrap">
<button class="btn">Default</button>
<button class="btn btn-primary"><i class="ri-check-line"></i> Default</button>
<button class="btn btn-icon" aria-label="Default icon"><i class="ri-refresh-line"></i></button>
<span class="chip chip-lg"><span class="chip-label">Default chip</span></span>
<a class="btn" href="#sizes">Default link</a>
</div>
<div class="dr-row-wrap">
<button class="btn btn-lg">Large</button>
<button class="btn btn-lg btn-primary"><i class="ri-check-line"></i> Large</button>
<button class="btn btn-lg btn-icon" aria-label="Large icon"><i class="ri-refresh-line"></i></button>
<a class="btn btn-lg" href="#sizes">Large link</a>
</div>
</div>
Icon-only
.btn-icon is not optional. A bare .btn keeps its
text padding, so one glyph sits in a box half again as wide as it is tall — and next to a
.btn-icon elsewhere in the same app the two do not match.
.btn-icon squares it against .btn's own
min-height, so it lines up with the text buttons beside it in both directions.
Give every icon-only button an aria-label — there is no text for a screen
reader to read — and a data-tip when the glyph alone does not say what will
happen. .btn-sm squares to the smaller size with it.
<button class="btn">Return to queue</button>
<button class="btn btn-icon" aria-label="Refresh" data-tip="Reload the list from the server."><i class="ri-refresh-line"></i></button>
<button class="btn btn-icon" aria-label="Copy link" data-tip="Copy a direct link to this item to the clipboard."><i class="ri-link"></i></button>
<button class="btn btn-icon btn-primary" aria-label="Save"><i class="ri-save-line"></i></button>
<button class="btn btn-icon btn-sm" aria-label="Unpin"><i class="ri-pushpin-line"></i></button>
Ghost
.btn-ghost defers its border and fill until hover, for a dense row of
secondary actions — a table row's actions, a toolbar. Everything the button
does is still there; only the chrome waits. It keeps the same box as a
bordered button, so a ghost and a solid button in one row still line up.
<button class="btn btn-ghost btn-icon" type="button" aria-label="More actions" data-tip="Rename, duplicate, export."><i class="ri-more-2-fill"></i></button>
<button class="btn btn-ghost" type="button"><i class="ri-eye-line"></i> Preview</button>
<button class="btn btn-ghost btn-sm" type="button"><i class="ri-download-2-line"></i> Export</button>
<button class="btn" type="button">Reassign</button>
A name that is read but not shown
.visually-hidden takes text out of the rendering and leaves it in the
accessibility tree. Use it where aria-label would replace a name the reader
can already partly see — here the button shows a count, and the hidden span says what the
count is of. It is not display:none or a zero-size box: both drop the element
from the accessibility tree too, which is the opposite of the point.
<button class="btn">
<i class="ri-notification-3-line"></i> 12
<span class="visually-hidden">unread notifications</span>
</button>
<a class="btn btn-primary" href="#skip-target">
Continue <span class="visually-hidden">to the approval step</span>
</a>
As a link
.btn works on an <a> — it sets its own
text-decoration and colour, so no reset is needed.
<a class="btn" href="#"><i class="ri-external-link-line"></i> Open in the warehouse</a>
<a class="btn btn-sm" href="#">Details</a>
In a footer row
Cancel on the left of the primary, primary last — the reading order ends on the action.
<div class="modal-footer" style="width:100%; border-top:none; padding:0;">
<button class="btn">Cancel</button>
<button class="btn btn-go"><i class="ri-send-plane-line"></i> Approve & send</button>
</div>
Floating action button
.fab is one page-level action, pinned to a corner on a screen too small to show
a toolbar. Deliberately not a general pattern: a second one has no obvious place, and the
first already covers whatever is under it. .fab--icon is the circular,
label-in-an-aria-label form.
It sits on the topbar's z-index rung — chrome at the same level, and it must stay below every
overlay so a modal covers it. Shown here position:static; in an app it is fixed
to the corner.
<div class="dr-row-wrap">
<button class="fab" type="button" style="position:static">
<i class="ri-add-line"></i> New order
</button>
<button class="fab fab--icon" type="button" style="position:static" aria-label="New order">
<i class="ri-add-line"></i>
</button>
</div>