Buttons & Selection
Buttons
Elements that trigger an immediate action. Styles are reset to the browser's default style.
<button style="all: revert">Click</button>Predefines roles
Buttons can have predefined actions for forms.
<div style="display: flex; gap: 1ex">
<button type="submit" style="all: revert">Submit</button>
<button type="reset" style="all: revert">Reset</button>
</div>.fancy-button {
padding: 0.3em 0.6em;
font-size: 1rem;
font-weight: 600;
color: white;
background-color: #3b82f6;
border: none;
border-radius: 0.5em;
cursor: pointer;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
transition: background-color 0.2s ease, transform 0.1s ease;
&:hover {
background-color: #2563eb;
}
&:active {
transform: scale(0.97);
}
&:focus-visible {
outline: 2px solid #93c5fd;
outline-offset: 2px;
}
}Styling buttons
<button class="fancy-button">Styled button</button>.fancy-button {
padding: 0.3em 0.6em;
font-size: 1rem;
font-weight: 600;
color: white;
background-color: #3b82f6;
border: none;
border-radius: 0.5em;
cursor: pointer;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
transition: background-color 0.2s ease, transform 0.1s ease;
&:hover {
background-color: #2563eb;
}
&:active {
transform: scale(0.97);
}
&:focus-visible {
outline: 2px solid #93c5fd;
outline-offset: 2px;
}
}Button with icon
You can put arbitrary HTML elements inside the button, such das icons. Make sure to adjust the spacing, for example using flex-box.
Here, an icon from an icon font is used, see Icons.
<button class="fancy-button with-icon">
<span class="material-icons">send</span>
Send
</button>.with-icon {
display: inline-flex;
align-items: center;
gap: 0.5em;
}Different visual roles
<div style="display: flex; gap: 1ex">
<button class="fancy-button primary">Primary</button>
<button class="fancy-button secondary">Secondary</button>
<button class="fancy-button danger">Danger</button>
</div>.fancy-button {
&.secondary {
background-color: #6b7280;
}
&.secondary:hover {
background-color: #4b5563;
}
&.danger {
background-color: #ef4444;
}
&.danger:hover {
background-color: #dc2626;
}
}Split button with menu
A split button with menu can be implemented using two buttons styled in a way so that they form one visual entity.
<div class="split-button" role="group">
<button class="main-action">Save</button>
<button class="dropdown-toggle"
aria-haspopup="menu"
aria-expanded="false"
aria-controls="save-options"
aria-label="More save options"
id="save-toggle"
popovertarget="save-options">
<span class="material-icons" aria-hidden="true">arrow_drop_down</span>
</button>
</div>
<ul id="save-options" role="menu" popover anchor="save-toggle">
<li role="none"><button type="button" role="menuitem">Save as draft</button></li>
<li role="none"><button type="button" role="menuitem">Export...</button></li>
</ul>.split-button {
display: inline-flex;
button {
border: none;
padding: 0.5em 1em;
background: #3b82f6;
color: white;
cursor: pointer;
transition: background 0.2s ease;
&:hover {
background: #2563eb;
}
&:first-child {
border-radius: 0.5em 0 0 0.5em;
padding-right: 0.5em;
}
&:last-child {
border-radius: 0 0.5em 0.5em 0;
padding-left: 0.5em;
display: grid;
place-items: center;
anchor-name: --anchor_1;
}
}
}
ul[role="menu"] {
position-anchor: --anchor_1;
top: anchor(bottom);
right: anchor(right);
left: auto;
bottom: auto;
min-width: 12rem;
margin-top: .25rem;
padding: .25rem;
border: 1px solid #ccc;
background: white;
border-radius: .5rem;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
li {
margin: 0;
padding: 0;
button {
width: 100%;
text-align: left;
padding: .5rem;
border-radius: .4rem;
&:hover,
&:focus-visible {
background: #f3f4f6;
}
}
}
}WARNING
The mechanism for the popup menu is currently only available in Chrome from version 125
Toolbar button
<button class="toolbar-button" aria-label="Edit">
<span class="material-icons">edit</span>
</button>
.toolbar-button {
width: 2.5em;
height: 2.5em;
border: none;
background: none;
cursor: pointer;
border-radius: 0.4em;
display: inline-flex;
align-items: center;
justify-content: center;
transition: background 0.2s ease;
}
.toolbar-button:hover {
background-color: #e5e7eb;
}
.toolbar-button:focus-visible {
outline: 2px solid #60a5fa;
outline-offset: 2px;
}
.material-icons {
font-size: 1.4em;
}Toggle Controls (On/Off, Many-of-Many)
Allow toggling of states or selecting multiple options:
<input type="checkbox" id="terms">
<label for="terms">Accept terms</label>HTML label element ensures that the label is also clickable
Styling checkbox
Change tickbox using emoji
Icon only: Ex: Photoshop layer view
Animations for transitioning
- Up down
- Only down
- Maybe without clip but fade?
- Same for horizontal
- 90 degree rotate with fade
- Cube transition
- Zoom in/out
- Flip
- Fade Without clip:
- Zoom out fade / reveal
Lottie animation?
- Opening Eye?
Mobile style switcher
You can do it with CSS [1], but there is also a native version on the horizon [2]. WebKit already has support [3]
Exclusive Selection (One-of-Many)
Choose one option among several:
<input type="radio"><select>(single mode)- Tab group (via ARIA)
<input type="radio" name="color" value="red" checked> Red
<input type="radio" name="color" value="blue"> BlueMulti-Selection
Choose multiple options from a list:
<select multiple>- Checkbox groups
<select multiple>
<option>Apple</option>
<option>Banana</option>
<option>Cherry</option>
</select>Accessibility Considerations
- Use semantic HTML whenever possible
- Provide visible labels or use
aria-label - Maintain keyboard operability (
tab,space,enter) - Avoid
div-based buttons unless roles and interactions are fully replicated
Related Topics
- Icons – for visual enhancement of controls
References
Native switcher in Webkit: Blog article ↩︎