Como o Ionic aplica estilos
No Ionic, a estilização combina CSS padrão com um sistema de variáveis CSS (CSS Custom Properties) que controlam cores, tipografia, espaçamentos e estados dos componentes. A maior parte dos componentes Ionic usa Shadow DOM ou estilos encapsulados, então nem sempre um seletor CSS “comum” alcança elementos internos. Por isso, o caminho recomendado para manter consistência é: definir o tema via variáveis e, quando necessário, personalizar componentes com CSS variables do próprio componente e/ou part selectors (quando suportado).
Escopo de estilos: global vs por componente
Estilos globais (consistência do app)
Use estilos globais para regras que devem valer no app inteiro: paleta, tipografia base, espaçamentos utilitários e ajustes de componentes que serão iguais em todas as telas. Em projetos Ionic/Angular, isso normalmente fica em arquivos como src/global.scss e/ou src/theme/variables.scss (o nome pode variar conforme o template).
- Quando usar: tema (cores), fonte padrão, estilos utilitários (ex.: classes de margem/padding), ajustes globais de componentes.
- Vantagem: consistência e menos repetição.
- Cuidado: seletores muito genéricos podem causar conflitos (ex.:
button { ... }).
Estilos por componente/página (isolamento)
Use o arquivo de estilo do componente/página (ex.: home.page.scss) para regras específicas daquela tela. Em Angular, por padrão, esses estilos são encapsulados (scoped) e não “vazam” para outras páginas.
- Quando usar: layout específico, ajustes pontuais, variações locais de componentes.
- Vantagem: reduz conflitos.
- Cuidado: não duplicar regras de tema; prefira variáveis globais.
Como evitar conflitos de CSS
- Evite seletores globais genéricos (ex.:
input,label,div). Prefira classes utilitárias ou seletores mais específicos. - Use classes com intenção (ex.:
.card--compact,.form-section), em vez de “estilizar pelo caminho” (ex.:ion-content ion-list ion-item ...). - Prefira variáveis CSS para cores e espaçamentos, em vez de valores “hardcoded”.
- Entenda o encapsulamento: se um estilo não aplica, provavelmente o elemento está dentro do Shadow DOM; use variáveis do componente ou
::partquando disponível.
Variáveis de tema do Ionic: paleta, tipografia e cores
O Ionic expõe variáveis globais (como --ion-color-primary) e também um conjunto de variáveis por componente (como --background, --color, --border-radius etc.). A ideia é definir a identidade visual no tema e deixar os componentes “herdarem” essa identidade.
Passo a passo: definir uma paleta consistente
1) Escolha cores principais e de suporte (primária, secundária, sucesso, alerta, perigo, neutros). 2) Garanta contraste adequado entre texto e fundo. 3) Mapeie essas cores nas variáveis do Ionic.
- Ouça o áudio com a tela desligada
- Ganhe Certificado após a conclusão
- + de 5000 cursos para você explorar!
Baixar o aplicativo
Exemplo (em src/theme/variables.scss ou arquivo equivalente):
:root { /* Cores base do tema */ --ion-color-primary: #2f6fed; --ion-color-primary-rgb: 47,111,237; --ion-color-primary-contrast: #ffffff; --ion-color-primary-contrast-rgb: 255,255,255; --ion-color-primary-shade: #295fd1; --ion-color-primary-tint: #447ef0; --ion-color-secondary: #12b981; --ion-color-secondary-contrast: #0b1f16; --ion-color-tertiary: #7c3aed; --ion-color-success: #16a34a; --ion-color-warning: #f59e0b; --ion-color-danger: #ef4444; /* Neutros (úteis para fundos e textos) */ --app-surface: #ffffff; --app-surface-2: #f6f7fb; --app-text: #111827; --app-text-muted: #6b7280;}Dica: além das variáveis do Ionic, crie variáveis próprias (como --app-surface) para padronizar superfícies e textos. Isso facilita trocar o visual sem caçar valores pelo projeto.
Passo a passo: tipografia e escala de texto
Para manter legibilidade, defina fonte base, tamanhos e pesos. Você pode ajustar variáveis globais e também criar uma escala tipográfica própria.
:root { --app-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif; --app-font-size-base: 16px; --app-line-height: 1.5; --app-h1: 28px; --app-h2: 22px; --app-body: 16px; --app-small: 13px;}Aplicando globalmente (em global.scss):
ion-app { font-family: var(--app-font-family); font-size: var(--app-font-size-base); line-height: var(--app-line-height); color: var(--app-text);}h1 { font-size: var(--app-h1); }h2 { font-size: var(--app-h2); }p, ion-label { font-size: var(--app-body); }Boas práticas: evite reduzir demais o texto (abaixo de ~14px) em conteúdos longos; use --app-text-muted para informações secundárias sem perder contraste.
Modo escuro (opcional, mas recomendado)
Para um design consistente, defina também variáveis para dark mode. Uma abordagem comum é sobrescrever variáveis em um seletor que represente o modo escuro (por exemplo, usando uma classe no body ou preferências do sistema).
body.dark { --app-surface: #0b1220; --app-surface-2: #0f1a2e; --app-text: #e5e7eb; --app-text-muted: #9ca3af; --ion-color-primary: #7aa2ff; --ion-color-primary-contrast: #0b1220;}Assim, componentes que usam essas variáveis se adaptam sem reescrever CSS por tela.
Personalização de componentes mantendo consistência
Em vez de “forçar” estilos internos, prefira ajustar as CSS variables do componente. Muitos componentes Ionic expõem variáveis como --background, --color, --border-radius, --padding-start etc.
Botões: raio, altura, contraste e estados
Objetivo: botões com aparência consistente (tamanho, cantos, texto) e contraste adequado.
Exemplo global (em global.scss):
ion-button { --border-radius: 12px; --padding-top: 14px; --padding-bottom: 14px; text-transform: none; letter-spacing: 0; font-weight: 600;}ion-button.button-solid { --box-shadow: 0 10px 24px rgba(var(--ion-color-primary-rgb), 0.22);}ion-button.button-outline { --border-width: 2px;}Acessibilidade: garanta contraste entre texto e fundo (ex.: --ion-color-primary-contrast). Evite usar apenas cor para indicar estado; combine com ícone, texto ou variação de borda.
Inputs: foco visível, preenchimento e mensagens de erro
Inputs precisam de foco claro (para teclado e leitores de tela) e espaçamento confortável.
Exemplo com ion-item + ion-input (estilo de formulário):
/* Classe utilitária para agrupar campos */.form-field { --background: var(--app-surface); --border-radius: 12px; --padding-start: 12px; --inner-padding-end: 12px; --min-height: 52px; margin: 10px 0; border: 1px solid rgba(17, 24, 39, 0.10);}body.dark .form-field { border-color: rgba(229, 231, 235, 0.14);}/* Foco visível */.form-field.ion-focused { border-color: rgba(var(--ion-color-primary-rgb), 0.8); box-shadow: 0 0 0 4px rgba(var(--ion-color-primary-rgb), 0.18);}/* Texto e placeholder */ion-input { --color: var(--app-text); --placeholder-color: var(--app-text-muted); --placeholder-opacity: 1;}Uso no template:
<ion-item class="form-field" lines="none"> <ion-label position="stacked">Email</ion-label> <ion-input type="email" inputmode="email" autocomplete="email" placeholder="voce@exemplo.com"></ion-input></ion-item>Passo a passo para estados de erro: 1) crie uma classe (ex.: .is-invalid) no ion-item; 2) altere borda e mensagem; 3) mantenha contraste e não dependa só de vermelho.
.form-field.is-invalid { border-color: rgba(var(--ion-color-danger-rgb, 239,68,68), 0.9); box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.14);} .field-hint { font-size: var(--app-small); color: var(--app-text-muted); margin-top: 6px;} .field-error { font-size: var(--app-small); color: var(--ion-color-danger); margin-top: 6px;}Listas e itens: densidade, separadores e hierarquia visual
Listas são comuns em apps mobile. O objetivo é manter leitura rápida: bom espaçamento, separadores discretos e hierarquia (título vs descrição).
ion-list { background: transparent;}ion-item.app-item { --background: var(--app-surface); --padding-start: 14px; --inner-padding-end: 14px; --min-height: 56px; margin: 10px 0; border-radius: 14px; border: 1px solid rgba(17, 24, 39, 0.08);}body.dark ion-item.app-item { border-color: rgba(229, 231, 235, 0.12);}ion-item.app-item ion-label h3 { margin: 0; font-size: 16px; font-weight: 600; color: var(--app-text);}ion-item.app-item ion-label p { margin: 4px 0 0; font-size: 13px; color: var(--app-text-muted);}Uso:
<ion-list> <ion-item class="app-item" button detail="true"> <ion-label> <h3>Notificações</h3> <p>Gerencie alertas e preferências</p> </ion-label> </ion-item></ion-list>Trabalhando com Shadow DOM: quando usar ::part e quando usar variáveis
Se você tentar estilizar um elemento interno de um componente Ionic e nada acontecer, provavelmente ele está encapsulado. Nesses casos:
- Primeira opção: procure e use as CSS variables do componente (ex.:
ion-button,ion-item,ion-input). - Segunda opção: use
::part(...)se o componente expuser “parts” estiláveis. - Terceira opção: evite
!important; se precisar, reavalie o seletor/abordagem.
Exemplo conceitual com ::part (o nome do part varia por componente):
/* Exemplo: ajustar parte interna exposta pelo componente */ion-searchbar::part(container) { border-radius: 14px;}Se o componente não expuser o part desejado, prefira ajustar o que for possível via variáveis e composição (envolver em um container com fundo/spacing) em vez de tentar “furar” o encapsulamento.
Construindo um mini “design system” no tema
Para manter design consistente, crie tokens (variáveis) para decisões recorrentes: raio, espaçamentos, sombras e superfícies. Isso reduz divergências entre telas e facilita manutenção.
Passo a passo: tokens de espaçamento, raio e sombra
:root { --app-radius-sm: 10px; --app-radius-md: 14px; --app-radius-lg: 18px; --app-space-1: 6px; --app-space-2: 10px; --app-space-3: 14px; --app-shadow-1: 0 10px 24px rgba(17, 24, 39, 0.10);}Aplicando em componentes:
ion-card.app-card { border-radius: var(--app-radius-lg); box-shadow: var(--app-shadow-1); background: var(--app-surface);}ion-card.app-card ion-card-title { color: var(--app-text);}ion-card.app-card ion-card-subtitle { color: var(--app-text-muted);}Checklist rápido: acessibilidade e legibilidade ao personalizar
| Item | O que verificar | Exemplo prático |
|---|---|---|
| Contraste | Texto vs fundo com contraste suficiente | Use --ion-color-*-contrast e evite cinzas muito claros |
| Foco visível | Elementos interativos mostram foco claramente | .ion-focused com borda/outline e sombra suave |
| Tamanho de toque | Alvos de toque confortáveis | Botões/itens com ~44–48px de altura |
| Hierarquia | Título, descrição e ações distinguíveis | h3 com peso maior e p com cor “muted” |
| Consistência | Mesmos raios, espaçamentos e cores em telas diferentes | Tokens --app-* aplicados globalmente |