Buttons
Summary
Buttons trigger actions or, when used as <a class="neura-button">,
navigate to a destination. Five visual variants (standard, primary,
link, subtle, compact) plus disabled, pressed, dropdown-trigger,
and split-button compositions.
When to use
| Variant | Use it for |
|---|---|
Primary.neura-button-primary |
The main action of a form or dialog. Use exactly one per surface. |
Standard.neura-button |
Secondary actions and neutral controls. |
Link.neura-button-link |
Actions that should look like a link but behave like a button (e.g. dialog Cancel). |
Subtle.neura-button-subtle |
Visually quiet buttons, often icon-only, used in toolbars. |
Compact.neura-button-compact |
Modifier for any variant; reduces height for tight rows. |
Dropdown / split.neura-dropdown2-trigger |
Combine with any variant when the button opens a menu (see Dropdowns). |
Examples
All variants rendered live: hover or tab to any button to verify focus and pressed states. The dropdown and split triggers open real menus; click outside or press Esc to close.
Variants
Compact
Disabled
Pressed (toggle state)
With icon
Button group
Dropdown button
Split button (with dropdown)
HTML
Standard button. Use <a> instead of <button> if the action is a navigation.
<button class="neura-button">Click me</button>
<a class="neura-button" href="/somewhere">Go</a>
Variants are added by appending a modifier class:
<button class="neura-button neura-button-primary">Save</button>
<button class="neura-button neura-button-link">Cancel</button>
<button class="neura-button neura-button-subtle">More</button>
<button class="neura-button neura-button-compact">Tiny</button>
Disabled: prefer the disabled attribute. aria-disabled="true" is honoured for non-form-submit cases.
<button class="neura-button" disabled>Disabled</button>
<button class="neura-button" aria-disabled="true">Disabled (a11y only)</button>
Toggle / pressed state: use aria-pressed.
<button class="neura-button" aria-pressed="true">Pressed</button>
Icon + text. The icon picks up currentColor from the button.
<button class="neura-button">
<span class="neura-icon neura-icon-plus"></span>
Add item
</button>
Icon-only: always include aria-label.
<button class="neura-button neura-button-subtle" aria-label="Edit">
<span class="neura-icon neura-icon-pencil"></span>
</button>
Button group: wrap siblings in .neura-buttons to fuse their borders.
<div class="neura-buttons">
<button class="neura-button">One</button>
<button class="neura-button">Two</button>
<button class="neura-button">Three</button>
</div>
Split button: primary action fused with a dropdown trigger.
<div class="neura-buttons">
<button class="neura-button neura-button-split-main">Save</button>
<button class="neura-button neura-button-split-more neura-dropdown2-trigger"
aria-controls="split-menu"
aria-label="More save options"></button>
</div>
<div id="split-menu" class="neura-dropdown2 neura-style-default" aria-hidden="true">
<ul>
<li><a href="#">Save</a></li>
<li><a href="#">Save and close</a></li>
<li><a href="#">Save as draft</a></li>
</ul>
</div>
CSS classes
| Class | Effect |
|---|---|
.neura-button | Base button styles. Required on every variant. |
.neura-button-primary | Blue gradient + white text. Use for the dominant action. |
.neura-button-link | Renders as a hyperlink: no background, blue text. |
.neura-button-subtle | Borderless until hover. Common for icon buttons in toolbars. |
.neura-button-compact | Reduced vertical padding for tight rows. Combine with any variant. |
.neura-buttons | Wrapper that fuses the borders of adjacent buttons into a group. Inside a group, .neura-button-primary reverts to the standard look (link-colored text) so it doesn't break the cluster (matches AUI). |
.neura-button-split-main | Left half of a split button (primary action). |
.neura-button-split-more | Right half of a split button (chevron-only dropdown trigger). Combine with .neura-dropdown2-trigger. |
.neura-dropdown2-trigger | Adds a CSS-drawn chevron arrow on the right edge. Use with aria-controls="…" pointing to the menu. Any redundant inner chevron span (.neura-icon-chevron-down) is hidden automatically. |
.neura-dropdown2-trigger-arrowless | Suppresses the chevron on a dropdown trigger that should look like a plain button (AUI: aui-dropdown2-trigger-arrowless). |
Adjacent sibling buttons space themselves automatically:
.neura-button ~ .neura-button and
.neura-buttons + .neura-buttons get a 10px start
margin, so a simple row needs no wrapper.
Attributes & states
| Attribute | Effect |
|---|---|
disabled | Native disabled state: prevents click + form submission. Preferred. |
aria-disabled="true" | Visually disabled but still focusable. Use only when disabled is unsuitable. |
aria-pressed="true" | Toggle button in pressed state. Pair with click handler that flips the value. |
.is-active | Class equivalent of the :active pressed look, for buttons that should render depressed programmatically. On .neura-button-split-more it also keeps the split divider in its hover state. |
.active | Set automatically by Neura.dropdown2 on the trigger while its menu is open (brings the chevron to full opacity); no need to manage it yourself. |
JavaScript
Buttons themselves are CSS-only; there is no
Neura.button(...) API. Wire your own click handlers
with addEventListener.
Plain click handler:
<button class="neura-button" id="save">Save</button>
<script>
document.getElementById('save').addEventListener('click', () => {
// your action here
console.log('saved');
});
</script>
Form submit: give the button type="submit" (the
default inside a <form>) and listen on the form:
<form id="profile-form">
<!-- fields -->
<button class="neura-button neura-button-primary" type="submit">Save</button>
<button class="neura-button neura-button-link" type="button" id="cancel">Cancel</button>
</form>
<script>
document.getElementById('profile-form').addEventListener('submit', (e) => {
e.preventDefault();
// submit via fetch / XHR
});
document.getElementById('cancel').addEventListener('click', () => history.back());
</script>
Toggle button: flip aria-pressed on click so the
CSS picks up the pressed state automatically:
<button class="neura-button" id="bold" aria-pressed="false">Bold</button>
<script>
const btn = document.getElementById('bold');
btn.addEventListener('click', () => {
const pressed = btn.getAttribute('aria-pressed') === 'true';
btn.setAttribute('aria-pressed', String(!pressed));
});
</script>
Delegated handler: one listener for many buttons (useful when buttons are rendered dynamically):
document.querySelector('.toolbar').addEventListener('click', (e) => {
const btn = e.target.closest('.neura-button[data-action]');
if (!btn) return;
const action = btn.dataset.action;
// dispatch on `action`
});
When a button opens a menu, the JS surface lives on the
dropdown - see Dropdowns for
Neura.dropdown2(trigger).show()/hide()/toggle().
AUI compatibility
Every .aui-button* class works identically: the
shim aliases them onto the .neura-button* rules
via Sass @extend. Existing Velocity templates can
use either prefix.
<!-- Both render identically: -->
<button class="aui-button aui-button-primary">Save</button>
<button class="neura-button neura-button-primary">Save</button>