07 / 25
All 25 in 25 CSS Button Groups
- 01CSS Split Button with Anchor-Positioned Popover Menu (Popover API, No JS)
- 02CSS Segmented Control with Motion-Path Comet Thumb (offset-path Arc Travel)
- 03CSS View Transitions Toggle Button Group with Morphing Thumb (Shared-Element FLIP)
- 04CSS Pricing Toggle with Monthly / Yearly Switch (Pure CSS, No JavaScript)
- 05CSS Segmented Control with Sliding Thumb Indicator (iOS-Style, Pure CSS)
- 06CSS Split Button Dropdown with Native <details> (Primary Action + Menu)
- 07CSS Icon Button Group for Toolbar Actions (Accessible Tooltips, Pure CSS)
- 08CSS Pill Radio Button Group with Sliding Indicator (Filter Pills, Pure CSS)
- 09CSS Toggle Button Group with Radio Inputs (Single-Select Alignment Group)
- 10CSS Wallet Connect Button Grid for Web3 Sign-In (MetaMask, WalletConnect, Coinbase)
- 11CSS AI Model Selector Button Group with Provider Badges (LLM Model Picker)
- 12CSS Segmented Control with Liquid Mercury Thumb (Metallic Stretch Animation)
- 13CSS Button Group with Subgrid Underline Beam (Perfectly Aligned Tab Indicator)
- 14CSS Multi-Select Chip Buttons with Acid Glow (Toggleable Tag Filters)
- 15CSS Split Button with Quantum Chevron Reveal (Animated Menu Materialize)
- 16CSS Format Toggle Button Group with Conic Fill (Radial Sweep Select)
- 17CSS Pixel Matrix Button Group with LED Segment Glow (Retro Display Buttons)
- 18CSS Multi-Action Button Group with Gradient Flow Progress (Animated CTA Bar)
- 19CSS Icon Segmented Control with Holographic Sheen (Iridescent View Switcher)
- 20CSS Vertical Button Stack with 3D Hover Depth (Tilting Card Buttons)
- 21CSS Floating Action Button with Radial Sub-Button Menu (Arc Fan-Out, Pure CSS)
- 22CSS Filter Button Group with RGB-Split Glitch Active State (Cyberpunk Toggle)
- 23CSS Pill Button Group with Rotating Conic Plasma Border (Animated Gradient Ring)
- 24CSS Action Button Row with Radar Shockwave Click Feedback (Ripple Pulse)
- 25CSS Date-Range Preset Button Group with Cursor-Following Glow (Spotlight Hover)
CSS Icon Button Group for Toolbar Actions (Accessible Tooltips, Pure CSS)
A fused icon toolbar like the ones in Figma, Notion and Google Docs: bold / italic / underline / link / code as a segmented row of icon buttons with hover tooltips, pressed states and proper labels. The complete 'CSS icon button group toolbar' pattern — every icon button keeps a real accessible name, a 44px hit area and a keyboard focus ring.
Build UI like this from scratch: Flexbox, Grid, animations & responsive CSS
ZTM · The CSS Bootcamp · 30‑day money-back guarantee · Affiliate link
The code
<section class="btn-07" aria-label="Icon button group toolbar demo">
<div class="btn-07__bar" role="toolbar" aria-label="Text formatting">
<button type="button" class="btn-07__tool" aria-label="Bold" aria-pressed="true" data-tip="Bold"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2.4"><path d="M7 5h6a3.5 3.5 0 0 1 0 7H7zM7 12h7a3.5 3.5 0 0 1 0 7H7z"/></svg></button>
<button type="button" class="btn-07__tool" aria-label="Italic" data-tip="Italic"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2.4"><path d="M14 5h-4M14 5l-4 14M14 19h-4"/></svg></button>
<button type="button" class="btn-07__tool" aria-label="Underline" data-tip="Underline"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2.4"><path d="M7 4v7a5 5 0 0 0 10 0V4M6 21h12"/></svg></button>
<span class="btn-07__div"></span>
<button type="button" class="btn-07__tool" aria-label="Insert link" data-tip="Link"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2.2"><path d="M10 13a4 4 0 0 0 5.7.6l2.6-2.6a4 4 0 0 0-5.6-5.7l-1.5 1.5M14 11a4 4 0 0 0-5.7-.6L5.7 13a4 4 0 0 0 5.6 5.7l1.5-1.5"/></svg></button>
<button type="button" class="btn-07__tool" aria-label="Inline code" data-tip="Code"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2.2"><path d="M9 8l-5 4 5 4M15 8l5 4-5 4"/></svg></button>
<span class="btn-07__div"></span>
<button type="button" class="btn-07__tool" aria-label="Clear formatting" data-tip="Clear"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2.2"><path d="M6 5h12M9 5l-2 14M15 5l1 7M5 19l14-14"/></svg></button>
</div>
</section><section class="btn-07" aria-label="Icon button group toolbar demo">
<div class="btn-07__bar" role="toolbar" aria-label="Text formatting">
<button type="button" class="btn-07__tool" aria-label="Bold" aria-pressed="true" data-tip="Bold"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2.4"><path d="M7 5h6a3.5 3.5 0 0 1 0 7H7zM7 12h7a3.5 3.5 0 0 1 0 7H7z"/></svg></button>
<button type="button" class="btn-07__tool" aria-label="Italic" data-tip="Italic"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2.4"><path d="M14 5h-4M14 5l-4 14M14 19h-4"/></svg></button>
<button type="button" class="btn-07__tool" aria-label="Underline" data-tip="Underline"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2.4"><path d="M7 4v7a5 5 0 0 0 10 0V4M6 21h12"/></svg></button>
<span class="btn-07__div"></span>
<button type="button" class="btn-07__tool" aria-label="Insert link" data-tip="Link"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2.2"><path d="M10 13a4 4 0 0 0 5.7.6l2.6-2.6a4 4 0 0 0-5.6-5.7l-1.5 1.5M14 11a4 4 0 0 0-5.7-.6L5.7 13a4 4 0 0 0 5.6 5.7l1.5-1.5"/></svg></button>
<button type="button" class="btn-07__tool" aria-label="Inline code" data-tip="Code"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2.2"><path d="M9 8l-5 4 5 4M15 8l5 4-5 4"/></svg></button>
<span class="btn-07__div"></span>
<button type="button" class="btn-07__tool" aria-label="Clear formatting" data-tip="Clear"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2.2"><path d="M6 5h12M9 5l-2 14M15 5l1 7M5 19l14-14"/></svg></button>
</div>
</section>.btn-07,
.btn-07 *,
.btn-07 *::before,
.btn-07 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.btn-07 {
--accent: oklch(0.7 0.17 135);
--ink: #1a2415;
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
display: flex;
align-items: flex-start;
justify-content: center;
background: linear-gradient(150deg,#20261c,#2c3626);
padding: 130px 20px;
}
.btn-07__bar {
display: inline-flex;
align-items: center;
gap: 2px;
padding: 6px;
background: #f4f7f0;
border-radius: 16px;
box-shadow: 0 20px 44px -20px rgba(0,0,0,.7),inset 0 0 0 1px rgba(255,255,255,.6);
}
.btn-07__tool {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 44px;
height: 44px;
border: none;
background: none;
color: #485a3d;
border-radius: 11px;
cursor: pointer;
transition: background .14s,color .14s;
}
.btn-07__tool:hover {
background: #e5ecdd;
color: var(--ink);
}
.btn-07__tool[aria-pressed=true] {
background: var(--accent);
color: #12200a;
}
.btn-07__div {
width: 1px;
height: 26px;
background: #d4ddca;
margin: 0 4px;
}
.btn-07__tool::after {
content: attr(data-tip);
position: absolute;
bottom: calc(100% + 10px);
left: 50%;
translate: -50% 0;
background: var(--ink);
color: #eef4e8;
font-size: 12px;
font-weight: 600;
padding: 5px 9px;
border-radius: 7px;
white-space: nowrap;
opacity: 0;
pointer-events: none;
transition: opacity .15s,translate .15s;
}
.btn-07__tool::before {
content: "";
position: absolute;
bottom: calc(100% + 5px);
left: 50%;
translate: -50% 0;
border: 5px solid transparent;
border-top-color: var(--ink);
opacity: 0;
transition: opacity .15s;
}
.btn-07__tool:hover::after,
.btn-07__tool:focus-visible::after {
opacity: 1;
translate: -50% -3px;
}
.btn-07__tool:hover::before,
.btn-07__tool:focus-visible::before {
opacity: 1;
}
.btn-07__tool:focus-visible {
outline: 3px solid var(--accent);
outline-offset: 2px;
z-index: 1;
}
@media (prefers-reduced-motion: reduce) {
.btn-07__tool,
.btn-07__tool::after {
transition: none;
}
}.btn-07,
.btn-07 *,
.btn-07 *::before,
.btn-07 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.btn-07 {
--accent: oklch(0.7 0.17 135);
--ink: #1a2415;
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
display: flex;
align-items: flex-start;
justify-content: center;
background: linear-gradient(150deg,#20261c,#2c3626);
padding: 130px 20px;
}
.btn-07__bar {
display: inline-flex;
align-items: center;
gap: 2px;
padding: 6px;
background: #f4f7f0;
border-radius: 16px;
box-shadow: 0 20px 44px -20px rgba(0,0,0,.7),inset 0 0 0 1px rgba(255,255,255,.6);
}
.btn-07__tool {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 44px;
height: 44px;
border: none;
background: none;
color: #485a3d;
border-radius: 11px;
cursor: pointer;
transition: background .14s,color .14s;
}
.btn-07__tool:hover {
background: #e5ecdd;
color: var(--ink);
}
.btn-07__tool[aria-pressed=true] {
background: var(--accent);
color: #12200a;
}
.btn-07__div {
width: 1px;
height: 26px;
background: #d4ddca;
margin: 0 4px;
}
.btn-07__tool::after {
content: attr(data-tip);
position: absolute;
bottom: calc(100% + 10px);
left: 50%;
translate: -50% 0;
background: var(--ink);
color: #eef4e8;
font-size: 12px;
font-weight: 600;
padding: 5px 9px;
border-radius: 7px;
white-space: nowrap;
opacity: 0;
pointer-events: none;
transition: opacity .15s,translate .15s;
}
.btn-07__tool::before {
content: "";
position: absolute;
bottom: calc(100% + 5px);
left: 50%;
translate: -50% 0;
border: 5px solid transparent;
border-top-color: var(--ink);
opacity: 0;
transition: opacity .15s;
}
.btn-07__tool:hover::after,
.btn-07__tool:focus-visible::after {
opacity: 1;
translate: -50% -3px;
}
.btn-07__tool:hover::before,
.btn-07__tool:focus-visible::before {
opacity: 1;
}
.btn-07__tool:focus-visible {
outline: 3px solid var(--accent);
outline-offset: 2px;
z-index: 1;
}
@media (prefers-reduced-motion: reduce) {
.btn-07__tool,
.btn-07__tool::after {
transition: none;
}
}Here's a working CSS Button Group from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: CSS Icon Button Group for Toolbar Actions (Accessible Tooltips, Pure CSS)
Source: https://codefronts.com/components/css-button-groups/css-icon-button-group-for-toolbar-actions-accessible-tooltips-pure-css/
A fused icon toolbar like the ones in Figma, Notion and Google Docs: bold / italic / underline / link / code as a segmented row of icon buttons with hover tooltips, pressed states and proper labels. The complete 'CSS icon button group toolbar' pattern — every icon button keeps a real accessible name, a 44px hit area and a keyboard focus ring.
## HTML
```html
<section class="btn-07" aria-label="Icon button group toolbar demo">
<div class="btn-07__bar" role="toolbar" aria-label="Text formatting">
<button type="button" class="btn-07__tool" aria-label="Bold" aria-pressed="true" data-tip="Bold"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2.4"><path d="M7 5h6a3.5 3.5 0 0 1 0 7H7zM7 12h7a3.5 3.5 0 0 1 0 7H7z"/></svg></button>
<button type="button" class="btn-07__tool" aria-label="Italic" data-tip="Italic"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2.4"><path d="M14 5h-4M14 5l-4 14M14 19h-4"/></svg></button>
<button type="button" class="btn-07__tool" aria-label="Underline" data-tip="Underline"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2.4"><path d="M7 4v7a5 5 0 0 0 10 0V4M6 21h12"/></svg></button>
<span class="btn-07__div"></span>
<button type="button" class="btn-07__tool" aria-label="Insert link" data-tip="Link"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2.2"><path d="M10 13a4 4 0 0 0 5.7.6l2.6-2.6a4 4 0 0 0-5.6-5.7l-1.5 1.5M14 11a4 4 0 0 0-5.7-.6L5.7 13a4 4 0 0 0 5.6 5.7l1.5-1.5"/></svg></button>
<button type="button" class="btn-07__tool" aria-label="Inline code" data-tip="Code"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2.2"><path d="M9 8l-5 4 5 4M15 8l5 4-5 4"/></svg></button>
<span class="btn-07__div"></span>
<button type="button" class="btn-07__tool" aria-label="Clear formatting" data-tip="Clear"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2.2"><path d="M6 5h12M9 5l-2 14M15 5l1 7M5 19l14-14"/></svg></button>
</div>
</section>
```
## CSS
```css
.btn-07,
.btn-07 *,
.btn-07 *::before,
.btn-07 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.btn-07 {
--accent: oklch(0.7 0.17 135);
--ink: #1a2415;
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
display: flex;
align-items: flex-start;
justify-content: center;
background: linear-gradient(150deg,#20261c,#2c3626);
padding: 130px 20px;
}
.btn-07__bar {
display: inline-flex;
align-items: center;
gap: 2px;
padding: 6px;
background: #f4f7f0;
border-radius: 16px;
box-shadow: 0 20px 44px -20px rgba(0,0,0,.7),inset 0 0 0 1px rgba(255,255,255,.6);
}
.btn-07__tool {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 44px;
height: 44px;
border: none;
background: none;
color: #485a3d;
border-radius: 11px;
cursor: pointer;
transition: background .14s,color .14s;
}
.btn-07__tool:hover {
background: #e5ecdd;
color: var(--ink);
}
.btn-07__tool[aria-pressed=true] {
background: var(--accent);
color: #12200a;
}
.btn-07__div {
width: 1px;
height: 26px;
background: #d4ddca;
margin: 0 4px;
}
.btn-07__tool::after {
content: attr(data-tip);
position: absolute;
bottom: calc(100% + 10px);
left: 50%;
translate: -50% 0;
background: var(--ink);
color: #eef4e8;
font-size: 12px;
font-weight: 600;
padding: 5px 9px;
border-radius: 7px;
white-space: nowrap;
opacity: 0;
pointer-events: none;
transition: opacity .15s,translate .15s;
}
.btn-07__tool::before {
content: "";
position: absolute;
bottom: calc(100% + 5px);
left: 50%;
translate: -50% 0;
border: 5px solid transparent;
border-top-color: var(--ink);
opacity: 0;
transition: opacity .15s;
}
.btn-07__tool:hover::after,
.btn-07__tool:focus-visible::after {
opacity: 1;
translate: -50% -3px;
}
.btn-07__tool:hover::before,
.btn-07__tool:focus-visible::before {
opacity: 1;
}
.btn-07__tool:focus-visible {
outline: 3px solid var(--accent);
outline-offset: 2px;
z-index: 1;
}
@media (prefers-reduced-motion: reduce) {
.btn-07__tool,
.btn-07__tool::after {
transition: none;
}
}
```Here's a working CSS Button Group from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: CSS Icon Button Group for Toolbar Actions (Accessible Tooltips, Pure CSS)
Source: https://codefronts.com/components/css-button-groups/css-icon-button-group-for-toolbar-actions-accessible-tooltips-pure-css/
A fused icon toolbar like the ones in Figma, Notion and Google Docs: bold / italic / underline / link / code as a segmented row of icon buttons with hover tooltips, pressed states and proper labels. The complete 'CSS icon button group toolbar' pattern — every icon button keeps a real accessible name, a 44px hit area and a keyboard focus ring.
## HTML
```html
<section class="btn-07" aria-label="Icon button group toolbar demo">
<div class="btn-07__bar" role="toolbar" aria-label="Text formatting">
<button type="button" class="btn-07__tool" aria-label="Bold" aria-pressed="true" data-tip="Bold"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2.4"><path d="M7 5h6a3.5 3.5 0 0 1 0 7H7zM7 12h7a3.5 3.5 0 0 1 0 7H7z"/></svg></button>
<button type="button" class="btn-07__tool" aria-label="Italic" data-tip="Italic"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2.4"><path d="M14 5h-4M14 5l-4 14M14 19h-4"/></svg></button>
<button type="button" class="btn-07__tool" aria-label="Underline" data-tip="Underline"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2.4"><path d="M7 4v7a5 5 0 0 0 10 0V4M6 21h12"/></svg></button>
<span class="btn-07__div"></span>
<button type="button" class="btn-07__tool" aria-label="Insert link" data-tip="Link"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2.2"><path d="M10 13a4 4 0 0 0 5.7.6l2.6-2.6a4 4 0 0 0-5.6-5.7l-1.5 1.5M14 11a4 4 0 0 0-5.7-.6L5.7 13a4 4 0 0 0 5.6 5.7l1.5-1.5"/></svg></button>
<button type="button" class="btn-07__tool" aria-label="Inline code" data-tip="Code"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2.2"><path d="M9 8l-5 4 5 4M15 8l5 4-5 4"/></svg></button>
<span class="btn-07__div"></span>
<button type="button" class="btn-07__tool" aria-label="Clear formatting" data-tip="Clear"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2.2"><path d="M6 5h12M9 5l-2 14M15 5l1 7M5 19l14-14"/></svg></button>
</div>
</section>
```
## CSS
```css
.btn-07,
.btn-07 *,
.btn-07 *::before,
.btn-07 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.btn-07 {
--accent: oklch(0.7 0.17 135);
--ink: #1a2415;
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
display: flex;
align-items: flex-start;
justify-content: center;
background: linear-gradient(150deg,#20261c,#2c3626);
padding: 130px 20px;
}
.btn-07__bar {
display: inline-flex;
align-items: center;
gap: 2px;
padding: 6px;
background: #f4f7f0;
border-radius: 16px;
box-shadow: 0 20px 44px -20px rgba(0,0,0,.7),inset 0 0 0 1px rgba(255,255,255,.6);
}
.btn-07__tool {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 44px;
height: 44px;
border: none;
background: none;
color: #485a3d;
border-radius: 11px;
cursor: pointer;
transition: background .14s,color .14s;
}
.btn-07__tool:hover {
background: #e5ecdd;
color: var(--ink);
}
.btn-07__tool[aria-pressed=true] {
background: var(--accent);
color: #12200a;
}
.btn-07__div {
width: 1px;
height: 26px;
background: #d4ddca;
margin: 0 4px;
}
.btn-07__tool::after {
content: attr(data-tip);
position: absolute;
bottom: calc(100% + 10px);
left: 50%;
translate: -50% 0;
background: var(--ink);
color: #eef4e8;
font-size: 12px;
font-weight: 600;
padding: 5px 9px;
border-radius: 7px;
white-space: nowrap;
opacity: 0;
pointer-events: none;
transition: opacity .15s,translate .15s;
}
.btn-07__tool::before {
content: "";
position: absolute;
bottom: calc(100% + 5px);
left: 50%;
translate: -50% 0;
border: 5px solid transparent;
border-top-color: var(--ink);
opacity: 0;
transition: opacity .15s;
}
.btn-07__tool:hover::after,
.btn-07__tool:focus-visible::after {
opacity: 1;
translate: -50% -3px;
}
.btn-07__tool:hover::before,
.btn-07__tool:focus-visible::before {
opacity: 1;
}
.btn-07__tool:focus-visible {
outline: 3px solid var(--accent);
outline-offset: 2px;
z-index: 1;
}
@media (prefers-reduced-motion: reduce) {
.btn-07__tool,
.btn-07__tool::after {
transition: none;
}
}
```How this works
The toolbar is a display:flex group of <button> elements sharing one rounded shell; inner corners are squared and a hairline divider separates each. Icons are inline SVG (crisp at any scale, currentColor-aware). Every button carries an aria-label so screen readers announce the action even though the visible content is only a glyph.
Toggle buttons (bold/italic) use aria-pressed and a CSS :has()-free approach: here the pressed look is driven by the demo's static markup, but in production you toggle the attribute. Tooltips are pure CSS — a ::after label + ::before arrow revealed on hover and :focus-visible, so keyboard users see them too.
.tool[aria-pressed=true]{ background:var(--accent); color:#fff }
.tool:hover::after,.tool:focus-visible::after{ opacity:1 }Techniques used: fused flex button group with shared shell + inner dividers · inline SVG icons with currentColor · aria-label names + aria-pressed toggles · pure-CSS ::after tooltips on hover AND focus · 44px minimum hit targets
Make it yours
--accenttints active/pressed buttons and focus rings.- Add or reorder tools freely — the flex shell and dividers self-adjust.
- Tooltip text comes from each button's
data-tipattribute. - Show tooltips below instead of above by flipping the
::afterposition.
Gotchas — read before shipping
- An icon button with no accessible name is invisible to screen readers — every one needs
aria-labelor visually-hidden text. - Toggle buttons must expose state via
aria-pressed, not color alone (WCAG 1.4.1). - Never shrink icon buttons below a 44×44px hit area on touch (WCAG 2.5.8).
- Tooltips built only on
:hoverexclude keyboard users — always include:focus-visibleas done here.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 15.4+ | 113+ | 111+ |
Floor set by oklch() as this demo is written. The core technique itself goes back further — Chrome all.
Pure CSS + inline SVG + ARIA attributes — works in every modern browser with no feature dependencies.