O que Sistema de Design de Alternadores e Interruptores faz?
Propósito
O Sistema de Design de Alternadores e Interruptores fornece um framework padronizado para projetar, posicionar e implementar controles de estado binário em interfaces web. Interruptores representam chaves físicas liga/desliga que acionam ou alteram imediatamente uma mudança de estado, definindo uma preferência ou status de recurso sem exigir uma etapa manual de envio de formulário (como clicar em "Salvar").
Sem um sistema de design dedicado para interruptores, as interfaces frequentemente usam interruptores no lugar de checkboxes, falham nos requisitos de contraste WCAG em estados desabilitados ou inativos, carecem de rótulos de estado claros, criam alvos de toque muito pequenos para telas móveis ou causam mudanças inesperadas de layout e efeitos colaterais em segundo plano sem feedback visual imediato.
Este sistema estabelece regras para geometria do interruptor, proporções da trilha e do polegar, alinhamento de rótulos, mapeamento de cores de estado, acessibilidade por teclado (role="switch"), expansão da área de toque, layouts de lista responsivos e estados de carregamento/pendente assíncrono.
Casos de Uso
- Configurações e Preferências de Aplicativos: Alternar preferências instantâneas do sistema (ex.: "Notificações Push", "Tema Escuro", "Salvar Rascunhos Automaticamente" ou "Autenticação de Dois Fatores").
- Seleção de Plano de Assinatura e Ciclo de Cobrança: Alternar entre ciclos de cobrança Mensal e Anual em cartões de preço com selos de desconto embutidos.
- Controle de Linha em Tabelas de Dados: Ativar ou desativar acesso de usuário individual, integrações de API, webhooks ou regras automatizadas diretamente nas linhas da tabela.
- Alternância de Flags de Recurso e Modos do Sistema: Alternar estados operacionais em painéis de desenvolvedor (ex.: "Modo de Manutenção", "Registro de Depuração" ou "Recursos Beta").
- Painéis de Consentimento de Cookies e Privacidade: Gerenciar permissões granulares de rastreamento (ex.: "Cookies de Análise", "Cookies de Marketing") em gavetas deslizantes ou diálogos modais.
Quando NÃO Usar
- Seleção de Múltiplas Opções: Para escolher entre 3 ou mais opções mutuamente exclusivas, use
sistema-de-controle-segmentadoousistema-de-selecao-personalizada-e-combobox. - Envios de Formulário que Exigem Aprovação Explícita: Para termos de acordo (ex.: "Aceito os Termos e Condições") dentro de um formulário padrão de vários campos que exige um clique no botão "Enviar", use checkboxes padrão (
sistema-de-design-de-formularios). - Escolha Binária com Efeito Não Imediato: Se a alternância do controle não entrar em vigor até que um botão secundário "Aplicar" ou "Salvar Alterações" seja pressionado, use uma checkbox em vez de um interruptor.
- Seleção em Massa em Tabelas: Para selecionar vários itens para operações em lote (ex.: "Excluir Selecionados"), use checkboxes (
sistema-de-ui-de-tabela-de-dados).
Entradas
- Definição de Estado: Parâmetros de estado binário (Desligado / Desmarcado /
falsevs. Ligado / Marcado /true). - Contexto e Modo de Execução: Mudança de estado imediata no lado do cliente (ex.: interruptor de tema escuro) vs. Efeito colateral assíncrono no servidor (ex.: ativar/desativar webhook de API).
- Estrutura de Rotulagem: Texto do rótulo embutido, texto de descrição/ajuda e necessidade de selo de status.
- Contexto de Layout: Cartão de configuração independente, linha densa de tabela, grupo de preferências com vários itens ou alternância de preço em destaque.
- Tema e Paleta de Tokens: Cores de superfície, cor da trilha ativa, cor da trilha inativa, cor do polegar e tokens de deslocamento do anel de foco.
Saídas
- Especificação de Geometria e Tokens do Interruptor: Dimensões espaciais para largura da trilha, altura, diâmetro do polegar, raio de canto e temporizações de transição (
largura: 44px,altura: 24px,polegar: 20px). - Blueprint de Estado e Contraste: Tokens de paleta garantindo contraste mínimo de 3:1 para objetos gráficos WCAG para trilhas e polegares nos estados Padrão (Desligado), Ativo (Ligado), Foco Visível, Desabilitado e Pendente.
- Especificação de Layout Estrutural e Tipografia: Relações de espaçamento entre o elemento interruptor, rótulo principal (
h4/span), texto de descrição e indicadores de status opcionais (LIGADO/DESLIGADO). - Mapeamento de Acessibilidade e ARIA: Estrutura HTML semântica
<button role="switch" aria-checked="true|false">com associação de rótulo para leitor de tela (aria-labelledby/aria-describedby). - Protocolo de Tratamento Assíncrono: Especificação de estado visual de carregamento (polegar com spinner ou opacidade reduzida da trilha) para verificação de rede em segundo plano.
Fluxo de Trabalho
1. Determinar a Semântica do Controle (Interruptor vs Checkbox)
Antes do design visual, confirme se a intenção da interação corresponde ao modelo mental de um interruptor físico:
- Efeito Imediato: A alternância do interruptor entra em vigor instantaneamente (ou aciona uma requisição imediata em segundo plano).
- Ação Independente: Opera de forma independente, sem precisar de um botão explícito de "Salvar" ou "Enviar".
- Metáfora de Estado Ligado/Desligado: Representa ativar ou desativar um recurso ou status, em vez de fazer uma seleção em um questionário de vários campos.
2. Estabelecer a Geometria Espacial e Margens de Toque
Projete componentes de interruptor com proporções que estejam alinhadas com as diretrizes de toque móvel, mantendo a harmonia visual no desktop:
[ TRILHA INATIVO / DESLIGADO ] [ TRILHA ATIVO / LIGADO ]
+--------------------------------+ +-------------------------------+
| (Polegar) | -----> | (Polegar) |
| 20px | | 20px |
+--------------------------------+ +-------------------------------+
<-------- 44px ------------------> <-------- 44px ----------------->
24px altura 24px altura
- Escala Padrão do Interruptor:
- Largura da Trilha:
44px(ou2.75rem) - Altura da Trilha:
24px(ou1.5rem) - Raio de Borda da Trilha:
999px(Forma de pílula completa) - Diâmetro do Polegar:
20px(deixando uma margem interna de2pxna trilha em todos os lados) - Raio de Borda do Polegar:
50%(Círculo)
- Largura da Trilha:
- Escala Compacta / Densa do Interruptor (Linhas de Tabela):
- Largura da Trilha:
36px - Altura da Trilha:
20px - Diâmetro do Polegar:
16px(com margem interna de2px)
- Largura da Trilha:
- Invólucro do Alvo de Toque:
- A zona de clique interativa DEVE ser expandida para pelo menos 44x44px em dispositivos móveis usando pseudo-elementos (
::before/::after) ou preenchimento, evitando cliques errados em telas sensíveis ao toque.
- A zona de clique interativa DEVE ser expandida para pelo menos 44x44px em dispositivos móveis usando pseudo-elementos (
3. Definir Tokens de Cor de Estado e Métricas de Contraste
Para atender aos requisitos de contraste não textual WCAG 2.1 / 2.2 AA (SC 1.4.11 - contraste mínimo de 3:1), siga pares estritos de tokens de cor:
- Estado Inativo / Desligado:
- Fundo da Trilha: Superfície cinza neutra (
#E2E8F0/ modo escuro:#334155). - Borda da Trilha: Borda de 1px (
#CBD5E1/ modo escuro:#475569) para garantir contraste de 3:1 contra superfícies de fundo claras. - Cor do Polegar: Branco sólido ou superfície clara (
#FFFFFF/ modo escuro:#F8FAFC). - Ícone Opcional dentro do Polegar: Ícone Lua/Sol ou Cruz/Check (
12px) para feedback visual duplo.
- Fundo da Trilha: Superfície cinza neutra (
- Estado Ativo / Ligado:
- Fundo da Trilha: Cor de ação do sistema ou marca de alto contraste (
#2563EBazul primário ou#16A34Averde sucesso). A taxa de contraste contra a superfície da página de fundo deve exceder 3:1. - Borda da Trilha: Transparente ou borda ativa correspondente.
- Cor do Polegar: Branco sólido (
#FFFFFF) com transição CSS suave (transform: translateX(20px)em200ms cubic-bezier(0.4, 0, 0.2, 1)).
- Fundo da Trilha: Cor de ação do sistema ou marca de alto contraste (
- Estados de Foco e Hover:
- Hover: Mudança sutil de brilho da trilha (+5% ou -5%) ou aumento da sombra do polegar (
box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.15)). - Foco Visível: Anel de foco distinto de 2px com deslocamento (
outline: 2px solid #2563EB; outline-offset: 2px).
- Hover: Mudança sutil de brilho da trilha (+5% ou -5%) ou aumento da sombra do polegar (
- Estado Desabilitado:
- Opacidade da Trilha e do Polegar: Reduzida para
0.5ou0.4comcursor: not-allowed.
- Opacidade da Trilha e do Polegar: Reduzida para
4. Alinhamento do Rótulo do Layout e Hierarquia da Descrição
Os interruptores devem sempre ser acompanhados por rótulos de texto claros. Nunca apresente um interruptor isolado sem um rótulo acessível ou contexto visível.
- Layout de Linha Horizontal (Cartão de Preferência Padrão):
- Coloque o bloco de texto à esquerda (Título + Descrição) e posicione o interruptor na borda direita.
- Alinhe o centro vertical da trilha do interruptor com a primeira linha do texto do título (não centralizado em descrições de várias linhas).
- Mantenha um espaçamento mínimo de
16pxentre o texto do título e o elemento interruptor.
- Layout Embutido em Formulário:
- Coloque o interruptor à esquerda e o texto do rótulo à direita (
gap: 12px), recomendado quando os interruptores são integrados em campos de formulário densos.
- Coloque o interruptor à esquerda e o texto do rótulo à direita (
- Layout de Alternância de Nível de Preço:
- Centralize o interruptor horizontalmente entre duas opções de rótulo explícitas (ex.: "Mensal" — [Interruptor] — "Anual (Economize 20%)"). Clicar em qualquer um dos rótulos de texto ou no interruptor alterna o estado ativo.
5. Lidar com Efeitos Colaterais Assíncronos e Estados de Carregamento
Quando um interruptor aciona uma chamada de API assíncrona (ex.: alterar uma configuração de recurso na nuvem ou ativar uma integração):
- Estado Visual Otimista: Deslize instantaneamente o polegar para a posição alvo (
aria-checked="true"). - Feedback Pendente: Renderize uma sobreposição sutil de spinner dentro do polegar ou reduza ligeiramente a opacidade da trilha durante a latência da rede.
- Recuperação de Erro: Se o servidor retornar um erro, exiba uma mensagem de alerta/toast embutida e anime suavemente o polegar de volta ao estado anterior com
aria-checked="false".
6. Implementar Padrões de Acessibilidade WCAG AA
Garanta navegação nativa por teclado e suporte a leitores de tela em todos os mecanismos de navegador:
- Marcação HTML Semântica:
<button type="button" role="switch" aria-checked="true" id="push-notifications-switch" aria-labelledby="push-notifications-label" aria-describedby="push-notifications-desc" class="toggle-switch"> <span class="toggle-switch__track"> <span class="toggle-switch__thumb"></span> </span> </button> - Interação por Teclado:
- Focalizável via navegação pela tecla
Tab. - Pressionar
EspaçoouEnteralterna o estadoaria-checked(true<->false) e aciona o manipulador associado.
- Focalizável via navegação pela tecla
- Anúncios do Leitor de Tela:
- Os leitores de tela anunciam explicitamente: "Notificações Push, interruptor, ligado" ou "Notificações Push, interruptor, desligado".
- NÃO escreva texto como "Ligado/Desligado" dentro do rótulo se isso duplicar o estado ARIA nativo do interruptor.
Regras de Decisão
Matriz de Seleção: Interruptor vs. Checkbox vs. Controle Segmentado
| Cenário / Requisito | Controle Recomendado | Motivo |
|---|---|---|
| Escolha binária única com efeito imediato (ex.: Tema Escuro) | Interruptor | Modelo de execução instantânea corresponde a um interruptor físico. |
| Escolha binária única dentro de um formulário enviado (ex.: Aceitar Termos) | Checkbox | As alterações não entram em vigor até que o botão "Enviar" seja clicado. |
| Seleção de vários itens de uma lista (ex.: Selecionar 5 e-mails) | Checkboxes | Comportamento padrão de seleção em lote. |
| Escolha entre 2 modos distintos (ex.: Visualização em Grade vs. Visualização em Lista) | Controle Segmentado | Ambos os rótulos de estado permanecem visíveis lado a lado. |
| Ativar/desativar uma opção em uma visualização de lista móvel | Interruptor | Alvo de polegar claro e feedback de estado explícito. |
Matriz de Posição do Rótulo
| Contexto de Layout | Posição do Interruptor | Posição do Rótulo | Comportamento Espacial |
|---|---|---|---|
| Lista de Preferências de Configurações | Alinhado à direita | Alinhado à esquerda | justify-content: space-between no contêiner da linha. |
| Campo de Formulário Embutido | Alinhado à esquerda | Alinhado à direita | display: inline-flex; align-items: center; gap: 12px. |
| Alternância de Preço em Destaque | Centralizado | Flanqueando Esquerda e Direita | Flanqueado pelas opções de texto "Mensal" e "Anual". |
Restrições
- Acessibilidade (WCAG 2.1 / 2.2 AA):
- Taxa de contraste não textual mínima de 3:1 para borda/fundo da trilha e polegar contra o fundo da página nos estados Ligado e Desligado.
- Taxa de contraste de texto mínima de 4.5:1 para todos os rótulos associados e texto de descrição auxiliar.
- O anel de foco deve fornecer pelo menos contraste de 3:1 contra o fundo circundante e medir pelo menos 2px de espessura.
- Alvos de Toque:
- A área de toque interativa deve medir pelo menos 44x44px em dispositivos de toque (WCAG 2.5.5 / 2.5.8).
- Independência de Cor:
- A cor NÃO deve ser o único indicador de estado. A posição espacial física do polegar (esquerda = desligado, direita = ligado) e o valor semântico
aria-checkeddevem comunicar o estado independentemente da cor.
- A cor NÃO deve ser o único indicador de estado. A posição espacial física do polegar (esquerda = desligado, direita = ligado) e o valor semântico
Padrões Comuns de Falha
- Uso Indevido de Interruptores em Formulários Enviados: Usar interruptores dentro de formulários onde as alterações não entram em vigor até clicar em um botão "Salvar" separado, confundindo os usuários que esperam aplicação instantânea.
- Contraste Inadequado da Trilha: Usar trilhas cinza claro (
#F1F5F9) contra fundos brancos sem uma borda delimitadora, tornando o interruptor invisível para usuários com baixa visão. - Comunicação de Estado Apenas por Cor: Depender estritamente de cores de trilha vermelha vs. verde sem mover a posição do polegar ou atualizar atributos ARIA.
- Alvos de Toque Microscópicos: Restringir a zona de clique à trilha visual de 36x20px, causando frustração e toques perdidos em viewports móveis.
- Rótulos Acessíveis Ausentes: Renderizar interruptores de ícone independentes sem um
aria-labelou referênciaaria-labelledby. - Sobreposição de Texto com Várias Linhas: Centralizar o interruptor verticalmente contra um parágrafo de descrição longo de 4 linhas, quebrando o alinhamento visual com o título principal.
Critérios de Validação
- O interruptor usa estrutura HTML semântica
<button role="switch" aria-checked="true|false">. - A trilha e o polegar satisfazem a taxa de contraste mínima de 3:1 contra o fundo nos estados LIGADO e DESLIGADO.
- A navegação por teclado (
Tab,Espaço,Enter) alterna suavemente o estado do interruptor e atualizaaria-checked. - A área de toque é estendida para pelo menos 44x44px usando preenchimento invisível ou pseudo-elementos.
- O interruptor é emparelhado com texto de rótulo visível e de alto contraste associado via
aria-labelledby. - A posição do interruptor faz a transição suave (
transform: translateX()) em 150ms–250ms com conformidadeprefers-reduced-motion. - Listas de configurações responsivas mantêm espaçamento adequado (
gap: 16px) sem sobreposição de texto em telas móveis estreitas.