Axismundi v3.5.2 · Wave 1
Icon button full-spec module
Baseline classes stay authoritative. This lab page catalogs the Icon button contract for variants, selected states, accessible names, and disabled handling without adding runtime JavaScript.
Experimental lab preview — source authority remains
components.css §3 plus icons.css §1/§5.
This page does not modify the public style guide.
§2. Variants
Four baseline variants, each rendered as a native button with an accessible name and an aria-hidden Material Symbols glyph.
§3. Selected / unselected states
Static catalog specimens — aria-pressed values are fixed;
no JS toggle handler. Production usage wires actual toggle behavior
at the integrator level (theme JS / block editor / plugin).
정적 카탈로그 specimen — aria-pressed 값 고정, JS toggle 없음.
실제 사용 시 통합 레벨(theme JS / block editor / plugin)에서 toggle handler 배선.
Filled · false
Filled · true
Tonal · false
Tonal · true
Outlined · false
Outlined · true
Standard · false
Standard · true
§4. Accessible name contract
Icon-only controls require a programmatic name. The visible glyph is
decorative and remains aria-hidden="true".
Named by aria-label
Named by aria-labelledby
Anti-pattern snippet — missing accessible name (not rendered)
<!-- Do not render this as a live control. The glyph is aria-hidden
and there is no aria-label / aria-labelledby. -->
<button class="ax-icon-button is-standard has-state-layer" type="button">
<span class="material-symbols-rounded" aria-hidden="true">search</span>
</button>
§5. Disabled — native attribute
Native disabled blocks activation and applies the baseline disabled styling for every variant.
§5a. Disabled — aria-disabled (plugin-managed)
aria-disabled="true" styles and announces state, but does
not block activation by itself. Use only when app/plugin code also
prevents activation.
aria-disabled="true"는 상태를 표시하고 전달하지만, 단독으로
activation을 차단하지 않는다. app/plugin 코드가 activation을 함께 막을 때만 사용.
Plugin-managed disabled
§6. has-state-layer opt-out
The baseline supports an explicit opt-out path. The specimen without
has-state-layer is expected to lack hover/focus opacity overlay.
With state-layer
state-layer 적용
No state-layer overlay
state-layer 생략
§7. Code snippets
Canonical variant
<button class="ax-icon-button is-standard has-state-layer" type="button" aria-label="Search">
<span class="material-symbols-rounded notranslate"
translate="no" aria-hidden="true" draggable="false">search</span>
</button>
Selected state
<button class="ax-icon-button is-tonal has-state-layer"
type="button" aria-label="Star selected" aria-pressed="true">
<span class="material-symbols-rounded notranslate"
translate="no" aria-hidden="true" draggable="false">star</span>
</button>
aria-labelledby
<span id="upload-label">Upload</span>
<button class="ax-icon-button is-tonal has-state-layer"
type="button" aria-labelledby="upload-label">
<span class="material-symbols-rounded notranslate"
translate="no" aria-hidden="true" draggable="false">upload</span>
</button>
Native disabled
<button class="ax-icon-button is-filled has-state-layer"
type="button" aria-label="Add" disabled>
<span class="material-symbols-rounded notranslate"
translate="no" aria-hidden="true" draggable="false">add</span>
</button>
aria-disabled — plugin-managed
<!-- App/plugin code must also prevent activation. -->
<button class="ax-icon-button is-filled has-state-layer"
type="button" aria-label="Sync paused" aria-disabled="true">
<span class="material-symbols-rounded notranslate"
translate="no" aria-hidden="true" draggable="false">sync</span>
</button>