Button — Full Spec Module
Component Full-Spec Module — baseline components.css §2
(L122–L234) is UNCHANGED at v3.5.1. This page demonstrates the
five variants × Phase 1-scoped states. Animated ripple is deferred
to Ripple v2 release (BACKLOG #25) per the Phase 2 pre-entry
decision (Option b).
Baseline catalog: ../../style-guide.html#components-button
has-state-layer (Pattern A:
currentColor overlay scaled by opacity tokens). Animated click-
position ripple is not wired at v3.5.1; it is a TARGET dependency
routed to the Ripple v2 release (BACKLOG #25).
§2. Variants — label only
다섯 가지 variant — filled / tonal / elevated / outlined / text.
S size (40px), corner-full radius (round). On press: corner-small
morph via spatial spring. All include has-state-layer.
§3. With leading icon
Canonical icon slot per BUTTON-SPEC-AUDIT.md §8 —
<span class="material-symbols-rounded ax-button-icon"
aria-hidden translate="no" draggable="false"> +
wrapped label.
§4. has-state-layer opt-out demo
Phase 1 SPEC §10 Risk 3 settled: default-ON canonical. This section demonstrates the opt-out path for completeness. Hover/ focus the two specimens to see the visual difference.
has-state-layer class applied — hover/focus shows
opacity overlay (Pattern A).
has-state-layer 적용 — hover/focus 시 opacity
overlay 표시 (Pattern A).
← has-state-layer class omitted — expected to lack
hover/focus opacity overlay. Not a bug; intentional
demonstration.
← has-state-layer class 생략 — hover/focus opacity
overlay 없음이 정상. 버그 아님, 의도된 시연.
§5. Disabled — native attribute (Pattern A §0.8)
All five variants with native disabled attribute.
Pattern A: 10% on-surface bg + 38% on-surface text + level0
box-shadow. Text variant retains transparent bg (baseline
L231–L234 exception).
Native disabled — browser blocks activation +
AT announces "disabled" + Pattern A visual rendering applied.
Native disabled — 브라우저가 activation 차단 + AT가
"disabled" 발화 + Pattern A 시각 렌더링 적용.
§5a. Disabled — aria-disabled (plugin-managed)
Single specimen with explicit caption. NOT a canonical
replacement for native disabled.
aria-disabled="true" visually mirrors Pattern A
via baseline L213
([aria-disabled="true"]) but does NOT block click
activation by itself. Use this form ONLY when the disabled
state is plugin-managed (e.g., a form plugin toggles
aria-disabled while the submit handler is in flight) and the
plugin's own JS prevents activation. For static / theme-side
disabled, prefer native disabled.
aria-disabled="true"는 baseline L213 선택자로
Pattern A 외관을 흉내내지만, 단독으로는 click activation을
막지 않는다. plugin이 disabled 상태를 동적으로 관리하면서
(예: form plugin이 submit handler 진행 중 aria-disabled를
토글), plugin JS가 activation을 직접 차단할 때만 이 형태를
사용. 정적 / theme-side disabled는 native disabled가
정답.
§6. Bare button
Rare-use base shape per SPEC §4.6. Receives base sizing + typography but no fill/color. Used for embedded contexts where styling comes from parent (split-button slave, custom block surface).
§7. Code snippets
Click each snippet to expand. Canonical markup for each variant family.
§2 Variants — label only (canonical)
<button class="ax-button is-filled has-state-layer t-label-large" type="button">Filled</button> <button class="ax-button is-tonal has-state-layer t-label-large" type="button">Tonal</button> <button class="ax-button is-elevated has-state-layer t-label-large" type="button">Elevated</button> <button class="ax-button is-outlined has-state-layer t-label-large" type="button">Outlined</button> <button class="ax-button is-text has-state-layer t-label-large" type="button">Text</button>
§3 With leading icon (canonical icon slot)
<button class="ax-button is-filled has-state-layer t-label-large" type="button">
<span class="material-symbols-rounded notranslate ax-button-icon"
translate="no" aria-hidden="true" draggable="false">add</span>
<span>Add</span>
</button>
§4 has-state-layer opt-out
<!-- Default (state-layer ON) --> <button class="ax-button is-filled has-state-layer t-label-large" type="button">With state-layer</button> <!-- Opt-out (state-layer OFF) --> <button class="ax-button is-filled t-label-large" type="button">Without state-layer</button>
§5 Disabled — native attribute (preferred)
<button class="ax-button is-filled has-state-layer t-label-large" type="button" disabled>Filled</button> <!-- ... text variant retains transparent bg per baseline L231-L234 exception --> <button class="ax-button is-text has-state-layer t-label-large" type="button" disabled>Text</button>
§5a aria-disabled — plugin-managed (use sparingly)
<!-- Plugin/JS must independently prevent activation; aria-disabled
alone does NOT block click. -->
<button class="ax-button is-filled has-state-layer t-label-large"
type="button" aria-disabled="true">aria-disabled</button>
§6 Bare button
<button class="ax-button has-state-layer t-label-large" type="button">Bare</button>
§8. Cross-references
Phase 0 · BUTTON-PHASE-0-REPORT.md
Phase 1 audit trio:
Phase 2 plan · BUTTON-PHASE-2-PLAN.md
Framework:
- MODULE-STATUS-MATRIX.md row #1 (Button)
- PROMOTION-CRITERIA.md §4.1 + §7
- PUBLIC-SURFACE-CHARTER.md §3 + §4
Baseline:
components.css§0 (state-layer) + §2 (Button)- style-guide.html #components-button
Animated ripple (TARGET — deferred): BACKLOG #25 — Ripple v2 contract.