Button
Buttons disparam ações. Disponível em 6 estilos e 3 tamanhos, com suporte a ícones, estado de carregamento e layout full-width.Buttons trigger actions. Available in 6 styles and 3 sizes, with support for icons, loading state, and full-width layout.
Quando usarWhen to use
<a>). Não use buttons para ações inline de texto ou quando o peso visual competiria com a ação principal da página.The action is navigation to another page or URL — use a link (<a>) instead. Don't use buttons for inline text actions or when the visual weight would compete with the page's primary action.
| EstiloStyle | Usar paraUse for | ÊnfaseEmphasis |
|---|---|---|
| Brand | Ação principal da página. Um por seção, idealmente um por página.Primary action on the page. One per section, ideally one per page. | MáximaHighest |
| Toned | Ações secundárias que precisam de visibilidade mas não devem competir com Brand.Secondary actions that need visibility but shouldn't compete with Brand. | MédiaMedium |
| Outline | Ações secundárias ou terciárias. Combina bem ao lado de um button Brand.Secondary or tertiary actions. Pairs well next to a Brand button. | MédiaMedium |
| Ghost | Ações terciárias, ações de toolbar ou buttons de fechar/dispensar.Tertiary actions, toolbar actions, or close/dismiss buttons. | BaixaLow |
| Success | Confirmar um resultado positivo: aprovar, concluir, publicar.Confirming a positive outcome: approve, complete, publish. | ContextualContextual |
| Danger | Ações destrutivas: excluir, remover, revogar. Sempre requer confirmação.Destructive actions: delete, remove, revoke. Always requires confirmation. | ContextualContextual |
AnatomiaAnatomy
2 Icon (opcional) — 16px, herda a cor do foreground. Posição esquerda ou direita.
3 Label (
.ds-btn__label) — conteúdo de texto, token de fonte semântico por tamanho.4 Padding raiz —
inset-sm (8px) / inset-md (12px) / inset-lg (16px).5 Padding do label — 4px adicionais (
inset-xs) quando não há ícone, para equilíbrio óptico.1 Container — background, border-radius, min-height per size.2 Icon (optional) — 16px, inherits foreground color. Left or right position.
3 Label (
.ds-btn__label) — text content, semantic font token per size.4 Root padding —
inset-sm (8px) / inset-md (12px) / inset-lg (16px).5 Label padding — additional 4px (
inset-xs) when no icon is present, for optical balance.
EstilosStyles
TamanhosSizes
| Size | AlturaHeight | FonteFont | Padding | Touch target |
|---|---|---|---|---|
Small (--sm) | 32px (semantic.size.control.sm) | semantic.typography.control.font-size.sm | 8×12px (padding-y × padding-x) | 32px — meets WCAG 2.5.8 min (24px) |
Medium (--md) | 40px (semantic.size.control.md) | semantic.typography.control.font-size.md | 10×16px (padding-y × padding-x) | 40px |
Large (--lg) | 48px (semantic.size.control.lg) | semantic.typography.control.font-size.lg | 12×20px (padding-y × padding-x) | 48px — meets AAA 44px target |
EstadosStates
Estados são controlados via pseudo-classes CSS (:hover, :active, :focus-visible, [disabled]), não classes modificadoras.States are handled via CSS pseudo-classes (:hover, :active, :focus-visible, [disabled]), not modifier classes.
| EstadoState | CSS trigger | Mudança visualVisual change | Token |
|---|---|---|---|
| Default | — | Preenchimento primárioPrimary fill | semantic.primary.background.default |
| Hover | :hover | Preenchimento mais escuroDarker fill | semantic.primary.bg-hover |
| Pressed | :active | Preenchimento mais escuro aindaDarkest fill | semantic.primary.bg-active |
| Focused | :focus-visible | Anel de 2px, offset de 2px2px outline ring, 2px offset | semantic.focus.ring.* |
| Disabled | [disabled] | Bg + fg atenuados, sem pointer eventsMuted bg + fg, no pointer events | semantic.background.disabled |
Com íconeWith icon
Somente íconeIcon only
CarregamentoLoading
Largura totalFull width
Boas práticasBest practices
Diretrizes de conteúdoContent guidelines
| RegraRule | ExemploExample |
|---|---|
| Use verbo + substantivo para clarezaUse verb + noun for clarity | "Save changes", "Add item", "Delete project" — não apenas "Submit" ou "OK""Save changes", "Add item", "Delete project" — not just "Submit" or "OK" |
| Use sentence caseUse sentence case | "Save changes" — não "Save Changes" ou "SAVE CHANGES""Save changes" — not "Save Changes" or "SAVE CHANGES" |
| Mantenha labels curtos (1–3 palavras)Keep labels short (1–3 words) | "Export CSV" — não "Click here to export your data as CSV""Export CSV" — not "Click here to export your data as CSV" |
| Seja específico sobre ações destrutivasBe specific about destructive actions | "Delete account" — não "Delete" ou "Remove""Delete account" — not "Delete" or "Remove" |
| Evite labels genéricosAvoid generic labels | "Confirm order" — não "Click here" ou "Yes""Confirm order" — not "Click here" or "Yes" |
Buttons somente-ícone precisam de aria-labelIcon-only buttons need aria-label | aria-label="Close dialog" — descreve a ação, não o íconearia-label="Close dialog" — describes the action, not the icon |
Mapeamento de tokensToken mapping
Tokens consumidos pela variante Brand. Outras variantes seguem o mesmo padrão usando seus respectivos grupos de cor.Tokens consumed by the Brand variant. Other variants follow the same pattern using their respective color groups.
| PropriedadeProperty | Token (semantic) | Variável CSSCSS variable |
|---|---|---|
| background (default) | semantic.primary.background.default | --ds-primary-background-default |
| background (hover) | semantic.primary.bg-hover | --ds-primary-background-hover |
| background (active) | semantic.primary.bg-active | --ds-primary-background-active |
| background (disabled) | semantic.background.disabled | --ds-background-disabled |
| text/icon color | semantic.primary.content-default | --ds-primary-content-default |
| text (disabled) | semantic.content.disabled | --ds-content-disabled |
| border-radius | semantic.radius.component | --ds-radius-md |
| focus ring | semantic.border.{focus,width.focus} | --ds-border-focus, --ds-border-width-focus (offset reusa width) |
| height (sm) | component.button.height.sm | --ds-button-height-sm |
| height (md) | component.button.height.md | --ds-button-height-md |
| height (lg) | component.button.height.lg | --ds-button-height-lg |
| padding-x (sm) | component.button.padding-x.sm | --ds-button-padding-x-sm |
| padding-x (md) | component.button.padding-x.md | --ds-button-padding-x-md |
| padding-x (lg) | component.button.padding-x.lg | --ds-button-padding-x-lg |
| padding-y (sm) | component.button.padding-y.sm | --ds-button-padding-y-sm (8px) |
| padding-y (md) | component.button.padding-y.md | --ds-button-padding-y-md (10px) |
| padding-y (lg) | component.button.padding-y.lg | --ds-button-padding-y-lg (12px) |
| gap (icon ↔ label) | component.button.gap | --ds-button-gap |
| font-size (sm) | component.button.font-size.sm | --ds-button-font-size-sm |
| font-size (md) | component.button.font-size.md | --ds-button-font-size-md |
| font-size (lg) | component.button.font-size.lg | --ds-button-font-size-lg |
| icon-size (sm) | component.button.icon-size.sm | --ds-button-icon-size-sm |
| icon-size (md) | component.button.icon-size.md | --ds-button-icon-size-md |
| icon-size (lg) | component.button.icon-size.lg | --ds-button-icon-size-lg |
Variante TonedToned variant
--ds-toned-background-default, --ds-toned-background-hover, --ds-toned-background-active) em vez de preenchimentos opacos. Isso difere dos padrões Subtle/Muted que usam tokens de background opacos. A abordagem translúcida permite que o button Toned se adapte naturalmente a qualquer cor de superfície abaixo dele, mantendo um tint de marca consistente.The Toned variant uses translucent overlay backgrounds (--ds-toned-background-default, --ds-toned-background-hover, --ds-toned-background-active) instead of opaque fills. This differs from Subtle/Muted patterns which use opaque background tokens. The translucent approach lets the Toned button adapt naturally to any surface color beneath it while maintaining a consistent brand tint.
Classes CSSCSS classes
| ClasseClass | DescriçãoDescription |
|---|---|
ds-btn | Classe base do buttonBase button class |
ds-btn--brand | Preenchido com cor da marca (estilo padrão, pode ser omitido)Filled with brand color (default style, can be omitted) |
ds-btn--toned | Background da marca com alpha transparenteAlpha-tinted brand background |
ds-btn--outline | Borda neutra, sem preenchimento de marcaNeutral border, no brand fill |
ds-btn--ghost | Texto da marca, sem background ou bordaBrand text, no background or border |
ds-btn--success | Preenchido com cor de sucesso/verdeFilled with success/green color |
ds-btn--danger | Preenchido com cor de erro/vermelhoFilled with error/red color |
ds-btn--sm | Tamanho pequeno (altura 32px)Small size (32px height) |
ds-btn--md | Tamanho médio (40px, padrão — pode ser omitido)Medium size (40px, default — can be omitted) |
ds-btn--lg | Tamanho grande (altura 48px)Large size (48px height) |
ds-btn--icon-only | Button quadrado para uso somente-íconeSquare button for icon-only use |
ds-btn--full | Button de largura total (100%)Full-width button (100%) |
ds-btn--loading | Estado de carregamento — oculta label, mostra spinnerLoading state — hides label, shows spinner |
ds-btn__label | Label de texto (elemento filho)Text label (child element) |
ds-btn__spinner | Container do spinner (elemento filho, usado com --loading)Spinner container (child element, used with --loading) |
Interação por tecladoKeyboard interaction
| TeclaKey | AçãoAction |
|---|---|
Tab | Move o foco para o button (ou além dele se desabilitado)Moves focus to the button (or past it if disabled) |
Enter | Ativa o buttonActivates the button |
Space | Activates the button |
Buttons desabilitados ([disabled]) são removidos da ordem de tabulação automaticamente pelo navegador. Buttons em carregamento também devem definir aria-disabled="true" para prevenir interação enquanto preservam a ordem de tabulação.Disabled buttons ([disabled]) are removed from tab order automatically by the browser. Loading buttons should also set aria-disabled="true" to prevent interaction while preserving tab order.
AccessibilityAccessibility
| Critério WCAGWCAG criterion | RequisitoRequirement | Status |
|---|---|---|
| 2.4.11 Focus Appearance (AA) | Focus ring 2px + gap de 2px, contraste ≥ 3:1 contra cores adjacentesFocus ring 2px + 2px gap, contrast ≥ 3:1 against adjacent colors | ✓ |
| 2.5.8 Target Size min (AA) | Menor tamanho (32px) excede o mínimo de 24pxSmallest size (32px) exceeds 24px minimum | ✓ |
| 2.5.5 Target Size (AAA) | Tamanho grande (48px) atende ao alvo de toque de 44pxLarge size (48px) meets 44px touch target | ✓ |
| 1.4.3 Contrast (AA) | Texto branco sobre Brand/Danger fill ≥ 4.5:1. Desabilitado isento.White text on Brand/Danger fill ≥ 4.5:1. Disabled exempt. | ✓ |
| 4.1.2 Name, Role, Value (A) | Use o elemento <button>. Somente-ícone requer aria-label.Use <button> element. Icon-only requires aria-label. | ✓ |
| 1.4.1 Use of Color (A) | Estado focado tem ring visível. Desabilitado tem texto esmaecido + opacidade reduzida.Focused state has visible ring. Disabled has dimmed text + reduced opacity. | ✓ |
aria-label — obrigatório em buttons somente-ícone.aria-disabled="true" + aria-busy="true" — definido em buttons em carregamento.disabled — use o atributo nativo para buttons realmente desabilitados (removidos da ordem de tabulação).aria-label — required on icon-only buttons.aria-disabled="true" + aria-busy="true" — set on loading buttons.disabled — use the native attribute for truly disabled buttons (removed from tab order).
Figma
O componente Figma possui 168+ variantes nas seguintes propriedades:The Figma component has 168+ variants across the following properties:
| PropriedadeProperty | TipoType | PadrãoDefault | OpçõesOptions |
|---|---|---|---|
| EstiloStyle | Variant | Brand | Brand, Toned, Outline, Ghost, Success, Danger |
| TamanhoSize | Variant | Medium | Small (32px), Medium (40px), Large (48px) |
| EstadoState | Variant | Default | Default, Hover, Pressed, Focused, Disabled |
| Icon Only | Variant | false | Default (com label), Icon Only (quadrado)Default (with label), Icon Only (square) |
| Loading | Boolean | false | true, false |
| Icon Left | Boolean | false | Alterna o slot de ícone esquerdoToggles left icon slot |
| Icon Right | Boolean | false | Alterna o slot de ícone direitoToggles right icon slot |