Component Contract
Icon Button / Link
A compact, icon-only control — the base atom behind share buttons, social links, close buttons, and toolbar actions.
Live Demo
Styles
Rendered
Default · Outline · Solid · Circle+Outline
Sizes
Rendered
sm (32px) · md (40px) · lg (48px)
States
Rendered
As link vs button
1. Summary
| Component name | Icon Button / Link |
|---|---|
| AEM resource type | caat/components/icon-button |
| Tier | Base (atom) — composes nothing but tokens |
| Purpose | A compact control showing only an icon, with an accessible name. The shared foundation for icon-only affordances across the system. |
| Variants | Style: ghost (default) · outline · solid · brand · Shape: square · circle · Size: sm · md · lg |
| Status | New |
Used by
As a base atom, Icon Button is consumed by other components rather than composing them (the reciprocal of a composite's “Composed of”). See docs/design-system-recommendations.md §F.
- Social / Share Links — each social/share affordance is an Icon Button (
--circle,--brand). - Navigation — footer social links, search/menu actions.
- Article Layout — the share row.
- Close affordances on Modal, Offcanvas, Toast, Alerts.
2. Design Tokens
| Token | Role |
|---|---|
--caat-color-action-primary | Default/ghost icon colour |
--caat-color-border | Outline border |
--caat-color-bg-page | Outline background |
--caat-color-bg-brand / --caat-color-text-inverse | Outline hover fill + icon |
--caat-color-state-hover-bg | Ghost hover background |
--caat-color-focus-ring | :focus-visible ring |
--caat-radius-sm / --caat-radius-pill | Square / circle shape |
--caat-opacity-disabled | Disabled state |
--caat-icon-btn-brand | Per-instance brand colour (set by Social Links) |
3. Authoring Fields
| Field | Type | Required | Notes |
|---|---|---|---|
| Icon | Icon picker | Yes | Bootstrap Icons name |
| Accessible label | Text | Yes | Becomes aria-label — describes the action/destination |
| Link / Action | Pathfield / Select | Yes | URL → renders <a>; action → renders <button> |
| Style | Select | Yes | ghost · outline · solid · brand |
| Shape | Select | No | square (default) · circle |
| Size | Select | No | sm · md (default) · lg |
4. Validation Rules
No author-managed content beyond an accessible label, so there are no authoring validation rules. Accessibility requirements are covered in Section 8 (Accessibility).
5. Content Guidance
Do
- Always provide a clear, action-oriented accessible label ("Share on LinkedIn", "Close dialog", "Copy link").
- Use only for universally-understood icons; if an icon is ambiguous, use a text Button instead.
- Use
--brandfor recognised platform colours (social),outlineon light surfaces,solidfor emphasis.
Don't
- Never ship an icon button without an accessible label.
- Don't shrink below the
sm(32px) size — keep the ≥24px target. - Don't use for primary CTAs — those need a visible text label (use Button).
6. Semantic HTML
<!-- Action (in-page) -->
<button type="button" class="caat-icon-btn caat-icon-btn--outline" aria-label="Copy link">
<i class="bi bi-link-45deg" aria-hidden="true"></i>
</button>
<!-- Link (navigation / external) -->
<a href="https://linkedin.com/company/caat-pension"
class="caat-icon-btn caat-icon-btn--circle caat-icon-btn--brand"
style="--caat-icon-btn-brand:#0a66c2;"
aria-label="CAAT on LinkedIn (opens in a new tab)" target="_blank" rel="noopener">
<i class="bi bi-linkedin" aria-hidden="true"></i>
</a>
7. CSS Contract
| Selector | Purpose |
|---|---|
.caat-icon-btn | Base — 40px, centred icon, transparent ghost |
.caat-icon-btn--outline / --solid / --brand | Style variants |
.caat-icon-btn--circle | Pill radius |
.caat-icon-btn--sm / --lg | 32px / 48px sizes |
:hover · :focus-visible · :active · :disabled | Full state matrix (token-driven) |
8. Accessibility
| Requirement | Implementation |
|---|---|
| Accessible name | Mandatory aria-label — there is no visible text. The glyph is aria-hidden="true". |
| Element | <button> for actions, <a> for links — never a bare <div>/<span>. |
| Keyboard | Natively focusable; Enter/Space (button) or Enter (link). Visible :focus-visible ring (3:1). |
| Target size | ≥ 40px (sm = 32px) — meets WCAG 2.5.8 (24px min). |
| Colour | Icon/background pairings inherit AA-verified semantic tokens. --brand colours must be checked when set. |
9. SEO
Transient / structural UI with no indexable content of its own — no SEO markup required. Ensure any content this component wraps or reveals stays server-rendered and crawlable.
10. Analytics
Analytics are captured through the shared data-analytics-component attribute on the component root (emitted automatically) and reported to the central data layer. Event names and payloads follow the organisation's standard analytics schema — defined centrally with the analytics team, not invented per component — so no bespoke tracking is specified here.
11. AEM Implementation Notes
- Resource type:
caat/components/icon-button. - Sling model exposes
icon,label,link,style,shape,size,brandColor. - HTL renders
<a>whenlinkis set, else<button>. - Primarily used as a building block via Sling delegation from Social Links, Navigation, etc.
12. Dialog Model (cq:dialog)
Not authored directly. The icon button is a sub-element emitted and configured by its host component (or generated from page structure), so it has no standalone cq:dialog — any options are exposed through the host component's dialog.
13. QA Checklist
| # | Check | Pass? |
|---|---|---|
| 1 | Every instance has a non-empty aria-label; glyph is aria-hidden | |
| 2 | Renders <a> for links, <button> for actions | |
| 3 | Focus ring visible on keyboard focus, on light and dark surfaces | |
| 4 | All sizes ≥ 24px target | |
| 5 | Disabled is non-focusable; hover/active distinct | |
| 6 | Brand colours pass contrast when used |
14. Definition of Done
- All style/shape/size variants render from tokens — no hard-coded colours.
- aria-label enforced by the dialog (required field).
- Accessibility audit — no violations; keyboard + focus verified.
- Consumed by Social/Share Links; duplication in article/nav removed.
- QA checklist signed off.