🎨 CSS

CSS — Dando vida às páginas

Do cinza sem graça ao layout incrível: aprenda a estilizar, posicionar e animar qualquer coisa com CSS. Da especificidade até animações suaves, tem tudo aqui.

🎨 Introdução ao CSS

CSS (Cascading Style Sheets — Folhas de Estilo em Cascata) é a linguagem responsável por toda a parte visual de uma página web. O HTML estrutura o conteúdo; o CSS decide como ele vai aparecer: cores, fontes, espaçamentos, layouts e até animações.

💡

Pense no HTML como a estrutura de uma casa e o CSS como a decoração, pintura e móveis. Sem CSS, a web seria uma lista enorme de texto sem formatação — tipo um documento do Bloco de Notas gigante.

Como funciona a Cascata

O "C" de CSS significa Cascata. Quando mais de uma regra CSS se aplica ao mesmo elemento, o navegador precisa decidir qual vence. Essa decisão envolve três fatores, nessa ordem de importância:

Fator O que é Exemplo
Origem De onde vem o estilo: browser padrão, autor ou usuário Seus estilos vencem o padrão do navegador
Especificidade Quão "específico" é o seletor #id vence .classe
Ordem A última regra igual declarada vence CSS mais abaixo no arquivo sobrescreve

Herança

Algumas propriedades CSS são herdadas pelos elementos filhos automaticamente. color, font-family e font-size são exemplos típicos. Outras como margin, padding e border não são herdadas — cada elemento cuida das suas próprias.

Como linkar CSS ao HTML

Existem três formas de aplicar CSS. A preferida é sempre a externa:

HTML — Externo (recomendado)
<!-- No <head> do HTML -->
<link rel="stylesheet" href="./assets/css/style.css">
HTML — Interno (evite para projetos reais)
<style>
  body {
    background: #0f1117;
  }
</style>
HTML — Inline (use apenas quando não tiver jeito)
<p style="color: red; font-size: 18px;">Texto vermelho</p>
⚠️

Inline CSS tem a maior especificidade (exceto !important), o que dificulta sobrescrever depois. Prefira sempre o CSS externo — manutenção muito mais fácil.

Sintaxe básica

A estrutura de uma regra CSS é sempre a mesma:

CSS — Anatomia de uma regra
/* seletor { propriedade: valor; } */

h1 {
  color: #6c63ff;
  font-size: 2rem;
  font-weight: 800;
}

/* Múltiplos seletores na mesma regra */
h1, h2, h3 {
  line-height: 1.3;
}

Especificidade — a tabela de pontos

Cada tipo de seletor tem um "peso". O navegador soma os pontos e a regra com maior pontuação vence.

Seletor Pontos Exemplo
* (universal) 0 * { }
Elemento / tag 1 p { }, div { }
Classe / pseudo-classe / atributo 10 .btn { }, :hover { }
ID 100 #header { }
Inline style 1000 style="..."
!important ∞ (evite!) color: red !important
CSS — Exemplo de especificidade
p { color: gray; }          /* pontos: 1 */
.destaque { color: blue; }  /* pontos: 10 — vence! */
#titulo { color: red; }      /* pontos: 100 — vence sobre os dois! */

/* Seletores combinados somam pontos */
div .btn:hover {
  /* 1 (div) + 10 (.btn) + 10 (:hover) = 21 pontos */
}

🎯 Seletores

Seletores são a forma de você dizer ao CSS "quero aplicar esse estilo neste(s) elemento(s)". Quanto mais você domina seletores, menos classes desnecessárias você cria no HTML.

Seletores básicos

CSS — Básicos
/* Elemento (tag) — aplica em todos os <p> */
p { color: #e2e8f0; }

/* Classe — aplica em qualquer elemento com class="card" */
.card { background: #1a1d27; }

/* ID — aplica apenas no elemento com id="header" */
#header { height: 60px; }

/* Universal — aplica em TUDO (use com cuidado) */
* { box-sizing: border-box; }

Combinadores

Combinam seletores para selecionar elementos baseados na sua relação no HTML:

CSS — Combinadores
/* Descendente (espaço) — qualquer <p> dentro de .artigo */
.artigo p { line-height: 1.8; }

/* Filho direto (>) — apenas <li> filho imediato de <ul> */
ul > li { list-style: none; }

/* Irmão adjacente (+) — <p> imediatamente após <h2> */
h2 + p { margin-top: 0; }

/* Irmão geral (~) — todos os <p> após <h2> no mesmo nível */
h2 ~ p { color: var(--text-muted); }

Pseudo-classes

Selecionam elementos num estado especial ou numa posição específica na estrutura:

CSS — Pseudo-classes
/* Estados de interação */
a:hover   { color: #6c63ff; }          /* mouse em cima */
input:focus  { outline: 2px solid #6c63ff; } /* campo focado */
button:active { transform: scale(0.97); }    /* clicando */

/* Posição na estrutura */
li:first-child  { font-weight: bold; }      /* primeiro filho */
li:last-child   { border-bottom: none; }    /* último filho */
li:nth-child(2) { color: #43d9ad; }        /* exatamente o 2º */
li:nth-child(odd)  { background: rgba(255,255,255,.03); } /* ímpares */
li:nth-child(3n)  { color: #ffd166; }     /* a cada 3 */

/* Negação */
input:not([type="submit"]) {
  border: 1px solid #2a2d3e;
}

Pseudo-elementos

Permitem estilizar partes específicas de um elemento ou inserir conteúdo via CSS sem mexer no HTML. Usam dois pontos duplos :::

CSS — Pseudo-elementos
/* Inserir conteúdo antes/depois do elemento */
.card::before {
  content: '🃏 ';
  display: inline-block;
}

.card::after {
  content: '';
  display: block;
  height: 2px;
  background: var(--accent);
}

/* Placeholder dos inputs */
input::placeholder {
  color: #8892a4;
  font-style: italic;
}

/* Texto selecionado pelo usuário */
::selection {
  background: rgba(108,99,255,.35);
  color: #fff;
}

Seletores de atributo

Selecionam elementos baseado nos seus atributos HTML — muito útil para formulários:

CSS — Atributos
/* Tem o atributo href (qualquer valor) */
a[href] { text-decoration: underline; }

/* Valor exato */
input[type="text"] { border-radius: 8px; }
input[type="checkbox"] { accent-color: #6c63ff; }

/* Começa com... */
[class^="btn"] { cursor: pointer; }

/* Termina com... */
a[href$=".pdf"]::after { content: ' 📄'; }

/* Contém... */
a[href*="external"] { color: var(--yellow); }

📦 Box Model

Todo elemento HTML é uma caixa retangular. O Box Model define como o tamanho dessa caixa é calculado. Entender isso evita aquele frustrantemente famoso "por que está estourando o layout?!".

As quatro camadas

De dentro para fora, cada caixa tem:

┌─────────────────────────────────────────────┐
                 MARGIN                  espaço fora da borda, transparente
  ┌───────────────────────────────────────┐  
                BORDER                 a linha visível ao redor
     ┌─────────────────────────────────┐     
                PADDING                 espaço interno, herda o fundo
        ┌───────────────────────────┐        
                CONTENT                 o texto/imagem de verdade
                                       
        └───────────────────────────┘        
     └─────────────────────────────────┘     
  └───────────────────────────────────────┘  
└─────────────────────────────────────────────┘

box-sizing: o herói silencioso

Por padrão (content-box), o width que você define se aplica apenas ao conteúdo — padding e border são somados por fora. Isso quebra layouts o tempo todo. Com border-box, o width inclui padding e border. Muito mais intuitivo.

content-box (padrão ruim)

.caixa {
  width: 200px;
  padding: 20px;
  border: 2px solid;
}
/* Tamanho real: 244px
   (200 + 20*2 + 2*2) */

border-box (use sempre!)

.caixa {
  box-sizing: border-box;
  width: 200px;
  padding: 20px;
  border: 2px solid;
}
/* Tamanho real: 200px. Sempre. */
🏆

Adicione isso no começo de todo projeto CSS e durma tranquilo:

*, *::before, *::after {
  box-sizing: border-box;
}

Propriedades do Box Model

CSS — Box Model completo
.caixa {
  /* Dimensões */
  width: 300px;
  height: 150px;
  max-width: 100%;    /* não ultrapassa o pai */
  min-height: 50px;  /* altura mínima */

  /* Padding — shorthand: top right bottom left */
  padding: 1rem;              /* todos os lados */
  padding: 1rem 2rem;        /* vertical | horizontal */
  padding: 10px 20px 10px 20px; /* t r b l */

  /* Margin */
  margin: 0 auto;  /* centraliza horizontalmente */

  /* Border */
  border: 1px solid #2a2d3e;
  border-radius: 8px;
}
⚠️

Margin collapse: margens verticais entre elementos irmãos se "colapsam" (a maior vence, não somam). Isso não acontece com padding. Fique esperto!

🔲 Display

A propriedade display define como um elemento se comporta no fluxo da página e como seus filhos são organizados. É uma das propriedades mais importantes do CSS.

Valor Comportamento Exemplos nativos
block Ocupa linha inteira, aceita width/height/margin vertical div, p, h1h6
inline Flui com o texto, ignora width/height, margens só horizontais span, a, strong
inline-block Flui com o texto MAS aceita width/height/margens verticais img, button
none Remove completamente do layout (não ocupa espaço) Qualquer elemento escondido
flex Ativa Flexbox no container; filhos viram flex items Navbars, cards em linha
grid Ativa CSS Grid no container; filhos viram grid items Layouts de página inteira
inline-flex Flex mas o container em si é inline Badges, botões com ícone
contents O container some, filhos sobem um nível no layout Trick para grupos de flex items
CSS — Display na prática
/* Esconder elemento sem tirar do DOM */
.escondido  { display: none; }
.invisivel  { visibility: hidden; } /* esconde mas ocupa espaço */

/* Botão com ícone alinhado */
.btn {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .6rem 1.2rem;
}

/* Trocar inline por block para estilizar */
span.destaque {
  display: block;
  width: 100%;
}

🔷 Flexbox

Flexbox é o sistema de layout unidimensional do CSS. Pense nele como uma prateleira: você define se os itens ficam em linha ou coluna, como se distribuem, como se alinham — e o navegador faz o trabalho pesado.

📚

Flexbox trabalha em um eixo por vez: main axis (principal) e cross axis (cruzado). O eixo principal é definido por flex-direction. Tudo gira em torno disso.

Propriedades do Container (pai)

CSS — Flex Container
.container {
  display: flex;

  /* Direção do eixo principal */
  flex-direction: row;           /* → padrão */
  flex-direction: row-reverse;   /* ← */
  flex-direction: column;        /* ↓ */
  flex-direction: column-reverse; /* ↑ */

  /* Quebra de linha */
  flex-wrap: nowrap;    /* padrão — tudo em uma linha */
  flex-wrap: wrap;      /* quebra pra próxima linha */

  /* Alinhamento no eixo principal (horizontal se row) */
  justify-content: flex-start;    /* ◀◀◀ padrão */
  justify-content: center;        /* ▶◀ centro */
  justify-content: flex-end;      /* ▶▶▶ */
  justify-content: space-between; /* ◀ · ▶ espaço entre */
  justify-content: space-around;  /* · ◀ · ▶ · espaço ao redor */
  justify-content: space-evenly;  /* espaço igual em tudo */

  /* Alinhamento no eixo cruzado (vertical se row) */
  align-items: stretch;     /* padrão — estica para preencher */
  align-items: center;      /* centraliza verticalmente */
  align-items: flex-start;  /* alinha no topo */
  align-items: flex-end;    /* alinha embaixo */
  align-items: baseline;    /* alinha pela linha de base do texto */

  /* Alinhamento de múltiplas linhas (quando wrap ativo) */
  align-content: center;

  /* Espaçamento entre itens */
  gap: 1rem;         /* linha e coluna */
  gap: 1rem 2rem;   /* linha | coluna */
}

Propriedades dos Items (filhos)

CSS — Flex Items
.item {
  /* flex-grow: quanto crescer para preencher espaço livre */
  flex-grow: 0;   /* padrão — não cresce */
  flex-grow: 1;   /* cresce para preencher */

  /* flex-shrink: quanto encolher quando faltar espaço */
  flex-shrink: 1;  /* padrão — pode encolher */
  flex-shrink: 0;  /* nunca encolhe */

  /* flex-basis: tamanho "ideal" antes de crescer/encolher */
  flex-basis: auto;    /* usa width/height */
  flex-basis: 200px;  /* tamanho base fixo */

  /* Shorthand flex: grow shrink basis */
  flex: 1;             /* flex: 1 1 0 */
  flex: 1 1 200px;

  /* Sobrescreve align-items só para este item */
  align-self: center;

  /* Ordem visual (não altera o DOM) */
  order: 2;  /* padrão é 0 */
}

Exemplos práticos

CSS — Navbar com Flexbox
.navbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 2rem;
  height: 60px;
}

.nav-logo { font-weight: bold; }

.nav-links {
  display: flex;
  gap: 1rem;
  list-style: none;
}
CSS — Card centralizado (o clássico)
.tela-login {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}
CSS — Footer sempre no fundo
body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

main {
  flex: 1; /* cresce para empurrar o footer */
}

footer {
  margin-top: auto;
}

⬛ CSS Grid

CSS Grid é o sistema de layout bidimensional do CSS — linhas E colunas ao mesmo tempo. Enquanto Flexbox é a prateleira, Grid é a planta baixa do apartamento inteiro. Perfeito para layouts de página e componentes complexos.

Propriedades do Container

CSS — Grid Container
.grid {
  display: grid;

  /* Colunas: 3 colunas de tamanhos diferentes */
  grid-template-columns: 200px 1fr 1fr;

  /* repeat() — repete o padrão N vezes */
  grid-template-columns: repeat(3, 1fr);
  grid-template-columns: repeat(4, minmax(200px, 1fr));

  /* auto-fill: preenche com o máximo de colunas que couber */
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));

  /* Linhas */
  grid-template-rows: 60px 1fr 50px;

  /* Espaçamentos */
  gap: 1rem;
  gap: 1.5rem 1rem; /* linha | coluna */
}

A unidade fr

fr significa fraction (fração). É a unidade do Grid que distribui o espaço disponível de forma proporcional. 1fr 2fr = a segunda coluna tem o dobro do tamanho da primeira. Super útil para layouts fluidos.

grid-template-areas — o superpoder

CSS — Layout de página com áreas nomeadas
.layout {
  display: grid;
  grid-template-columns: 220px 1fr;
  grid-template-rows: 60px 1fr 50px;
  min-height: 100vh;

  grid-template-areas:
    "header  header"
    "sidebar main  "
    "footer  footer";
}

header  { grid-area: header; }
.sidebar{ grid-area: sidebar; }
main    { grid-area: main; }
footer  { grid-area: footer; }

Posicionamento manual de itens

CSS — grid-column e grid-row
.destaque {
  /* Ocupa da coluna 1 até a 3 (2 colunas) */
  grid-column: 1 / 3;

  /* Atalho para "ocupa 2 colunas a partir da atual" */
  grid-column: span 2;

  /* Da linha 1 até a linha 2 */
  grid-row: 1 / 2;

  /* -1 significa "até o final" */
  grid-column: 1 / -1; /* ocupa a linha toda */
}

/* Cards responsivos sem media query — mágica! */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 1.2rem;
}
🎯

Regra geral: use Flexbox quando você pensa em uma dimensão (linha OU coluna). Use Grid quando você pensa em duas dimensões (linha E coluna ao mesmo tempo).

📱 Responsividade

Responsividade é fazer seu layout funcionar bem em qualquer tamanho de tela — do celular de 320px ao monitor 4K. Em 2024, mais de 60% do tráfego web vem de mobile. Ignorar isso é um erro caro.

Mobile-first: comece pelo menor

A abordagem mobile-first é simples: escreva o CSS base para celular e use min-width para adicionar estilos progressivamente em telas maiores. É mais fácil expandir do que comprimir.

Desktop-first (evite)

/* Base para desktop */
.grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

/* Quebra pra mobile */
@media (max-width: 768px) {
  .grid {
    grid-template-columns: 1fr;
  }
}

Mobile-first (prefira)

/* Base para mobile */
.grid {
  display: grid;
  grid-template-columns: 1fr;
}

/* Expande para desktop */
@media (min-width: 768px) {
  .grid {
    grid-template-columns: 1fr 1fr;
  }
}

Media Queries

CSS — Media Queries
/* Breakpoints comuns */
@media (min-width: 640px) { /* sm — celular grande */ }
@media (min-width: 768px) { /* md — tablet */ }
@media (min-width: 1024px) { /* lg — laptop */ }
@media (min-width: 1280px) { /* xl — desktop */ }

/* Orientação */
@media (orientation: landscape) { /* paisagem */ }
@media (orientation: portrait)  { /* retrato */ }

/* Combinando condições */
@media (min-width: 768px) and (max-width: 1024px) {
  /* só tablets */
}

/* Preferência de tema do sistema */
@media (prefers-color-scheme: dark) { /* modo escuro */ }
@media (prefers-reduced-motion: reduce) { /* desativa animações */ }

Unidades relativas

Unidade Relativa a Uso típico
% Elemento pai Larguras fluidas: width: 100%
vw Largura da viewport Seções full-width: width: 100vw
vh Altura da viewport Hero sections: min-height: 100vh
em Font-size do elemento atual Padding/margin em escala com o texto
rem Font-size do elemento raiz (html) Tipografia consistente no projeto
ch Largura do caractere "0" Largura de colunas de texto: max-width: 65ch
svh Small Viewport Height (sem barras do browser) Mobile: evita barras cobrindo conteúdo

clamp() — tipografia fluida

A função clamp(min, preferred, max) define um valor que cresce com a tela mas nunca sai de um intervalo. Perfeito para tamanhos de fonte responsivos sem media queries:

CSS — clamp() para tipografia fluida
h1 {
  /* Mínimo 1.8rem, ideal 5vw, máximo 3.5rem */
  font-size: clamp(1.8rem, 5vw, 3.5rem);
}

p {
  font-size: clamp(.9rem, 2.5vw, 1.1rem);
}

.hero {
  /* Padding que cresce com a tela */
  padding: clamp(2rem, 8vw, 6rem);
}

/* max-width com fluid — conteúdo não fica largo demais */
.container {
  width: min(90%, 1200px);
  margin: 0 auto;
}

🎨 Variáveis CSS

Variáveis CSS (tecnicamente chamadas de Custom Properties) permitem definir valores reutilizáveis diretamente no CSS — sem precisar de pré-processadores como Sass. Elas são dinâmicas (podem ser alteradas via JavaScript) e funcionam em cascata.

Sintaxe básica

CSS — Declarando e usando variáveis
/* Declarar no :root = disponível em todo o documento */
:root {
  --cor-primaria: #6c63ff;
  --cor-fundo: #0f1117;
  --espaco-base: 1rem;
  --fonte-titulo: 'Segoe UI', system-ui, sans-serif;
  --raio-borda: 8px;
}

/* Usar com var() */
.botao {
  background: var(--cor-primaria);
  padding: var(--espaco-base);
  border-radius: var(--raio-borda);
}

/* var() aceita fallback como segundo argumento */
.card {
  color: var(--cor-texto, #e2e8f0); /* usa #e2e8f0 se --cor-texto não existir */
}

Escopo local

Variáveis não precisam ser globais. Você pode declarar uma variável em qualquer seletor e ela só existe naquele contexto e nos filhos:

CSS — Escopo local de variáveis
.card-verde {
  --destaque: #43d9ad;
}

.card-roxo {
  --destaque: #6c63ff;
}

/* Ambas as classes usam a mesma propriedade */
.card .titulo {
  color: var(--destaque);
  border-bottom: 2px solid var(--destaque);
}

Tema dark/light com variáveis

A forma mais elegante de implementar dark mode. Você troca apenas as variáveis no :root e todo o site muda instantaneamente:

CSS — Dark/Light mode via variáveis
/* Tema claro (padrão) */
:root {
  --bg: #ffffff;
  --texto: #1a1a2e;
  --card-bg: #f5f5f5;
  --borda: #e0e0e0;
}

/* Tema escuro — via preferência do sistema */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0f1117;
    --texto: #e2e8f0;
    --card-bg: #1a1d27;
    --borda: #2a2d3e;
  }
}

/* Alternativa: classe no elemento raiz (toggle via JS) */
[data-theme="dark"] {
  --bg: #0f1117;
  --texto: #e2e8f0;
}

/* Todo o CSS usa as variáveis — nada muda aqui */
body { background: var(--bg); color: var(--texto); }
.card { background: var(--card-bg); border-color: var(--borda); }
JavaScript — Toggle de tema
const btn = document.querySelector('#toggle-tema');

btn.addEventListener('click', () => {
  const atual = document.documentElement.getAttribute('data-theme');
  document.documentElement.setAttribute(
    'data-theme',
    atual === 'dark' ? 'light' : 'dark'
  );
});

✨ Animações

Animações bem feitas comunicam estado, guiam o olhar e tornam a experiência mais prazerosa. Animações mal feitas deixam o site lento e irritam o usuário. A diferença está em usar as ferramentas certas.

transition — para estados

transition é usado para animar a mudança de um estado para outro (hover, focus, etc.). É a animação mais simples e eficiente:

CSS — Transitions
.botao {
  background: #6c63ff;
  transform: scale(1);

  /* transition: propriedade duração timing delay */
  transition: background .2s ease, transform .15s ease;

  /* Ou anima todas as propriedades (menos eficiente) */
  transition: all .2s ease;
}

.botao:hover {
  background: #5a52d5;
  transform: translateY(-2px);
}

.botao:active {
  transform: scale(.97);
}

/* Timing functions mais usadas */
transition-timing-function: ease;        /* suave no início e fim */
transition-timing-function: ease-in;     /* começa devagar */
transition-timing-function: ease-out;    /* termina devagar */
transition-timing-function: ease-in-out; /* devagar nos dois */
transition-timing-function: linear;      /* velocidade constante */
transition-timing-function: cubic-bezier(.4,0,.2,1); /* customizado */

@keyframes + animation — para sequências

Para animações mais complexas que não são simples transições de estado, use @keyframes para definir a sequência e animation para aplicá-la:

CSS — @keyframes e animation
/* Definindo a animação */
@keyframes pular {
  0%   { transform: translateY(0); }
  50%  { transform: translateY(-20px); }
  100% { transform: translateY(0); }
}

@keyframes girar {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

@keyframes aparecer {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Aplicando com animation */
.botao-pulante {
  /* animation: nome duração timing delay iteracao direction fill-mode */
  animation: pular .6s ease infinite;
}

.spinner {
  animation: girar 1s linear infinite;
}

.card {
  animation: aparecer .4s ease-out both;
}

/* Propriedades individuais */
.animado {
  animation-name: pular;
  animation-duration: .6s;
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;  /* ou um número */
  animation-fill-mode: both;            /* mantém estado final */
  animation-play-state: running;        /* paused para pausar */
}

transform — a propriedade para animar

CSS — Transform
.elemento {
  /* Mover */
  transform: translate(20px, -10px);  /* x, y */
  transform: translateX(50%);
  transform: translateY(-100%);

  /* Escalar */
  transform: scale(1.1);       /* 10% maior */
  transform: scale(.95);      /* 5% menor (clique) */
  transform: scaleX(1.2);     /* só horizontal */

  /* Rotacionar */
  transform: rotate(45deg);
  transform: rotate(-180deg);

  /* Torcer */
  transform: skew(10deg, 5deg);

  /* Combinar (ordem importa!) */
  transform: translateY(-4px) scale(1.02);
}

Exemplos divertidos

CSS — Botão saltitante
@keyframes bounce {
  0%, 100% {
    transform: translateY(0);
    animation-timing-function: cubic-bezier(.8,0,1,1);
  }
  50% {
    transform: translateY(-16px);
    animation-timing-function: cubic-bezier(0,0,.2,1);
  }
}

.btn-bounce:hover {
  animation: bounce .6s infinite;
}
CSS — Spinner de loading
@keyframes spin {
  to { transform: rotate(360deg); }
}

.spinner {
  width: 32px;
  height: 32px;
  border: 3px solid rgba(108,99,255,.2);
  border-top-color: #6c63ff;
  border-radius: 50%;
  animation: spin .8s linear infinite;
}
CSS — Fade in ao carregar
@keyframes fade-up {
  from {
    opacity: 0;
    transform: translateY(24px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.card {
  animation: fade-up .5s ease-out both;
}

/* Delay escalonado para lista de cards */
.card:nth-child(1) { animation-delay: 0s; }
.card:nth-child(2) { animation-delay: .1s; }
.card:nth-child(3) { animation-delay: .2s; }
🚀

Performance tip: anime apenas opacity e transform. Essas duas propriedades são processadas pelo compositor do browser (GPU) sem causar layout recalculation ou repaint. Evite animar width, height, top, left, margin — elas causam reflow e podem deixar a animação travada.

Respeite usuários com sensibilidade a movimento. Desabilite animações desnecessárias para quem configurou o sistema para reduzir movimento:

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}

Resumo do módulo CSS

  • CSS controla toda a apresentação visual — cores, layout, tipografia e animações
  • A cascata resolve conflitos por origem, especificidade e ordem de declaração
  • Prefira CSS externo; use box-sizing: border-box em todo projeto
  • Seletores combinados, pseudo-classes e pseudo-elementos eliminam classes desnecessárias
  • O Box Model define Content → Padding → Border → Margin — sempre use border-box
  • Flexbox para layouts unidimensionais; Grid para layouts bidimensionais
  • Mobile-first com min-width e unidades relativas para responsividade
  • Variáveis CSS (--custom-props) são essenciais para temas e manutenção
  • Anime apenas opacity e transform para performance máxima
  • Respeite prefers-reduced-motion para acessibilidade

Nesta página