Estilização no Ionic: CSS, variáveis de tema e design consistente

Capítulo 5

Tempo estimado de leitura: 8 minutos

+ Exercício

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 ::part quando 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.

Continue em nosso aplicativo e ...
  • Ouça o áudio com a tela desligada
  • Ganhe Certificado após a conclusão
  • + de 5000 cursos para você explorar!
ou continue lendo abaixo...
Download App

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

ItemO que verificarExemplo prático
ContrasteTexto vs fundo com contraste suficienteUse --ion-color-*-contrast e evite cinzas muito claros
Foco visívelElementos interativos mostram foco claramente.ion-focused com borda/outline e sombra suave
Tamanho de toqueAlvos de toque confortáveisBotões/itens com ~44–48px de altura
HierarquiaTítulo, descrição e ações distinguíveish3 com peso maior e p com cor “muted”
ConsistênciaMesmos raios, espaçamentos e cores em telas diferentesTokens --app-* aplicados globalmente

Agora responda o exercício sobre o conteúdo:

Ao tentar alterar a aparência interna de um componente do Ionic e perceber que um seletor CSS comum não funciona, qual abordagem é mais recomendada para manter consistência visual?

Você acertou! Parabéns, agora siga para a próxima página

Você errou! Tente novamente.

Muitos componentes usam Shadow DOM/estilos encapsulados, então seletores comuns podem não alcançar elementos internos. Para manter consistência, o recomendado é definir o tema por variáveis e ajustar componentes via variáveis próprias ou ::part quando disponível.

Próximo capitúlo

Responsividade no Ionic: adaptando para diferentes tamanhos de tela

Arrow Right Icon
Capa do Ebook gratuito Ionic para Iniciantes: aplicativos híbridos com HTML, CSS e TypeScript
24%

Ionic para Iniciantes: aplicativos híbridos com HTML, CSS e TypeScript

Novo curso

21 páginas

Baixe o app para ganhar Certificação grátis e ouvir os cursos em background, mesmo com a tela desligada.