CSS do básico ao mercado de trabalho
Um guia prático para quem já conhece HTML e quer dominar CSS de verdade — com exemplos renderizados ao vivo, exercícios com solução, mini-projetos para o portfólio e preparação para entrevistas. Fecha com um módulo de SCSS.
Como usar esta apostila
Cada seção segue o mesmo ritmo: conceito → código → resultado ao vivo → exercício. Os blocos tracejados roxos mostram o CSS realmente aplicado no seu navegador — esta própria página é estilizada com as técnicas que ela ensina (abra o código-fonte e confira!).
Você vai encontrar três tipos de destaque ao longo do caminho:
Recomendação de estudo: crie uma pasta estudos-css no seu computador, com um arquivo index.html e um style.css, e reproduza cada exemplo digitando (não copie e cole). Digitar cria memória muscular — e teste técnico é feito digitando.
Módulo 1.1 — O que é CSS e como aplicá-lo
CSS (Cascading Style Sheets) é a linguagem que controla a aparência do HTML: cores, tamanhos, espaçamentos, posicionamento, animações. O HTML é o esqueleto; o CSS é a pele, a roupa e o movimento.
Existem três formas de aplicar CSS a uma página:
<!-- 1. Inline: direto no elemento (evite — difícil de manter) -->
<p style="color: purple;">Texto roxo</p>
<!-- 2. Interno: dentro de <style> no <head> (ok para testes) -->
<style>
p { color: purple; }
</style>
<!-- 3. Externo: arquivo .css separado (padrão profissional) -->
<link rel="stylesheet" href="style.css">
Módulo 1.2 — Sintaxe e seletores básicos
Toda regra CSS tem a mesma anatomia:
seletor {
propriedade: valor; /* isto é uma declaração */
outra-propriedade: outro-valor;
}
Os 4 seletores que você usará todos os dias
| Seletor | Sintaxe | Seleciona | Exemplo |
|---|---|---|---|
| Elemento | p | Todas as tags daquele tipo | p { color: gray; } |
| Classe | .destaque | Elementos com class="destaque" | .destaque { font-weight: bold; } |
| ID | #topo | O único elemento com id="topo" | #topo { background: black; } |
| Universal | * | Todos os elementos | * { box-sizing: border-box; } |
Você também pode agrupar seletores com vírgula:
h1, h2, h3 {
font-family: 'Sora', sans-serif;
}
.importante, ficar vermelho e em negrito.
Ver solução
p { color: gray; }
.importante {
color: red;
font-weight: bold;
}
Módulo 1.3 — Cores e unidades de medida
Formas de escrever cores
.exemplos-de-cor {
color: purple; /* nome (140+ nomes existem) */
color: #663399; /* hexadecimal — o mais comum */
color: rgb(102, 51, 153); /* vermelho, verde, azul (0–255) */
color: rgba(102, 51, 153, .5); /* com transparência (0 a 1) */
color: hsl(270, 50%, 40%); /* matiz, saturação, luminosidade */
}
hsl() é o favorito de quem cria sistemas de cores: para clarear ou escurecer um tom, basta mudar o último número.
Unidades: quando usar cada uma
| Unidade | O que é | Use para |
|---|---|---|
px | Pixel fixo | Bordas, sombras, detalhes pequenos |
rem | Múltiplo da fonte raiz (16px por padrão) | Fontes, margens, paddings — respeita a configuração de acessibilidade do usuário |
em | Múltiplo da fonte do elemento pai | Espaçamentos relativos ao texto local |
% | Percentual do pai | Larguras fluidas |
vw / vh | % da largura/altura da tela | Seções de tela cheia, tipografia fluida |
rem é sempre relativo ao elemento raiz (html), previsível; em é relativo ao pai, então acumula em elementos aninhados. Por isso o mercado padronizou rem para quase tudo.Módulo 1.4 — Box model: o conceito mais importante do CSS
Todo elemento HTML é uma caixa com quatro camadas, de dentro para fora:
- Content — o conteúdo (texto, imagem);
- Padding — respiro interno, entre o conteúdo e a borda;
- Border — a borda em si;
- Margin — respiro externo, entre a caixa e as vizinhas.
.cartao {
width: 300px;
padding: 20px; /* respiro interno */
border: 2px solid #663399; /* borda */
margin: 16px; /* respiro externo */
}
/* Atalhos (sentido horário: cima, direita, baixo, esquerda) */
.atalhos {
margin: 10px 20px 10px 20px; /* os 4 lados */
margin: 10px 20px; /* vertical | horizontal */
margin: 0 auto; /* truque clássico: centraliza horizontalmente */
}
box-sizing: border-box — a primeira linha de todo projeto
Por padrão, width: 300px se refere só ao conteúdo — padding e borda são somados por fora, e a caixa fica maior do que você pediu. A correção universal:
* {
box-sizing: border-box; /* width agora inclui padding e borda */
}
border-box. Praticamente todo projeto profissional começa com um reset que inclui essa linha.width: 200px, padding: 20px e border: 5px solid, qual a largura total renderizada (a) no modelo padrão e (b) com border-box?
Ver solução
(a) 200 + 20 + 20 + 5 + 5 = 250px. (b) 200px — padding e borda passam a caber dentro dos 200px. Essa é literalmente uma pergunta de entrevista de estágio/júnior.
Módulo 1.5 — Tipografia
body {
font-family: 'Inter', Arial, sans-serif; /* lista de fallbacks */
font-size: 1rem; /* 16px */
font-weight: 400; /* 400 normal · 700 bold */
line-height: 1.6; /* sem unidade = múltiplo da fonte (melhor prática) */
letter-spacing: 0.01em;
}
h1 { text-transform: uppercase; }
a { text-decoration: none; }
p { text-align: left; } /* evite justify na web: cria "rios" de espaço */
Georgia, 22px, line-height 1.3 — título com serifa
Corpo de texto menor, line-height 1.8, cor suavizada — repare como só tipografia já cria hierarquia visual sem nenhuma imagem.
rem. Recrutadores técnicos reparam nisso em 5 segundos.Módulo 2.1 — Cascata, especificidade e herança
O "C" de CSS é Cascading: quando duas regras disputam o mesmo elemento, o navegador decide a vencedora por três critérios, nesta ordem:
- Especificidade — quão "preciso" é o seletor;
- Ordem — em empate, a última regra escrita vence;
- Origem — estilos do autor vencem os padrões do navegador.
Calculando especificidade
Pense em três placares (A, B, C):
| Placar | Vale para | Peso |
|---|---|---|
| A | IDs (#menu) | 1-0-0 |
| B | Classes, atributos, pseudo-classes (.btn, :hover) | 0-1-0 |
| C | Elementos e pseudo-elementos (p, ::before) | 0-0-1 |
p /* 0-0-1 */
.aviso /* 0-1-0 — vence p */
p.aviso /* 0-1-1 — vence .aviso */
#rodape .aviso /* 1-1-0 — vence todos acima */
!important atropela toda a cascata — e por isso é considerado último recurso. Se você precisa dele para "fazer funcionar", o problema quase sempre é especificidade mal organizada. Em entrevistas, dizer "resolvo com !important" é resposta errada; a certa é "reviso a especificidade dos seletores".Herança
Propriedades de texto (cor, fonte, line-height) são herdadas pelos filhos automaticamente. Propriedades de caixa (margin, padding, border, width) não são. Por isso definir font-family no body estiliza a página inteira.
Módulo 2.2 — Seletores avançados
Combinadores
nav a /* descendente: qualquer <a> dentro de nav, em qualquer nível */
nav > a /* filho direto: só <a> imediatamente dentro de nav */
h2 + p /* irmão adjacente: o <p> logo depois de um h2 */
h2 ~ p /* irmãos gerais: todos os <p> depois de um h2 */
Pseudo-classes essenciais
a:hover { color: purple; } /* mouse em cima */
input:focus { outline: 2px solid purple; } /* selecionado via clique/teclado */
li:first-child { font-weight: bold; }
li:last-child { border-bottom: none; }
li:nth-child(odd) { background: #f4f2ea; } /* zebra em tabelas/listas */
input:disabled { opacity: .5; }
li:not(.ativo) { color: gray; }
Pseudo-elementos
p::first-line { font-weight: bold; }
.btn::before { content: "→ "; } /* insere conteúdo decorativo via CSS */
::selection { background: #FFE066; } /* cor ao selecionar texto */
Teste agora: selecione qualquer texto desta apostila com o mouse — o fundo amarelo do destaque é um ::selection em ação... brincadeira, aqui usamos o padrão. Mas os balões "▶ Resultado ao vivo" e "💼 Dica de mercado" desta página são todos ::before!
Módulo 2.3 — Display e posicionamento
display: os três comportamentos clássicos
| Valor | Comportamento | Exemplos nativos |
|---|---|---|
block | Ocupa a linha inteira; aceita width/height | div, p, h1, section |
inline | Flui no texto; ignora width/height e margens verticais | span, a, strong |
inline-block | Flui no texto, mas aceita dimensões | — |
E o mais usado de todos: display: none remove o elemento da página (diferente de visibility: hidden, que esconde mas mantém o espaço ocupado — clássica pergunta de entrevista).
position
.estatico { position: static; } /* padrão: fluxo normal */
.relativo { position: relative; top: 10px; } /* desloca a partir de onde estava */
.absoluto { position: absolute; top: 0; right: 0; } /* ancora no ancestral posicionado mais próximo */
.fixo { position: fixed; bottom: 20px; } /* fixa na TELA (não rola) */
.grudento { position: sticky; top: 0; } /* rola até "grudar" no topo */
position: relative e o filho position: absolute para se ancorar nele (badge no canto do card, ícone dentro do input, botão de fechar no modal). O menu lateral desta apostila usa position: sticky.z-index controla quem fica por cima quando elementos se sobrepõem — mas só funciona em elementos posicionados (qualquer position exceto static).
Módulo 2.4 — Flexbox: layout em uma dimensão
Flexbox distribui itens em um eixo (linha OU coluna). É a ferramenta nº 1 para alinhar coisas: menus, botões lado a lado, centralização.
.container {
display: flex;
flex-direction: row; /* row (padrão) | column */
justify-content: space-between; /* eixo PRINCIPAL: flex-start | center | space-between | space-around */
align-items: center; /* eixo TRANSVERSAL: stretch | center | flex-start */
gap: 12px; /* espaço entre itens (adeus, margens manuais) */
flex-wrap: wrap; /* permite quebrar linha */
}
.item { flex: 1; } /* itens crescem igualmente para preencher */
↑ display:flex; gap:12px; com flex:1 em cada caixa.
A centralização perfeita (decore isto)
.centralizar {
display: flex;
justify-content: center; /* horizontal */
align-items: center; /* vertical */
min-height: 100vh;
}
display:grid; place-items:center) e o antigo margin: 0 auto (só horizontal). Explicar as três mostra senioridade.Ver solução
<nav class="navbar">
<span class="logo">MeuSite</span>
<div class="links">
<a href="#">Home</a> <a href="#">Sobre</a> <a href="#">Contato</a>
</div>
</nav>
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px 32px;
}
.links { display: flex; gap: 24px; }
Módulo 2.5 — Grid: layout em duas dimensões
Grid organiza linhas E colunas ao mesmo tempo. É a escolha para estruturas de página: galeria de cards, dashboard, layout com sidebar.
.galeria {
display: grid;
grid-template-columns: repeat(3, 1fr); /* 3 colunas de tamanho igual */
gap: 12px;
}
.destaque {
grid-column: span 3; /* este item ocupa as 3 colunas */
}
O padrão de galeria responsiva sem media query
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
Tradução: "crie quantas colunas couberem, cada uma com no mínimo 250px". Ao estreitar a tela, as colunas quebram sozinhas. Este snippet resolve 80% das galerias do mundo real — memorize-o.
Flexbox ou Grid?
| Use Flexbox quando… | Use Grid quando… |
|---|---|
| Alinhar itens em uma direção (menu, botões, ícone + texto) | Estruturar a página em áreas (header, sidebar, main) |
| O conteúdo define o tamanho | O layout define o tamanho |
| Componentes pequenos | Galerias e dashboards |
Módulo 2.6 — Sombras, bordas e gradientes
.card {
border-radius: 12px; /* cantos arredondados */
box-shadow: 0 4px 24px rgba(0,0,0,.12); /* x | y | blur | cor */
background: linear-gradient(135deg, #663399, #9B59D0);
}
.avatar { border-radius: 50%; } /* círculo perfeito */
.texto-sombra { text-shadow: 1px 1px 3px rgba(0,0,0,.3); }
.foco-suave { background: radial-gradient(circle, #fff, #F1EAF8); }
rgba(0,0,0,.1) a .15, com blur generoso (16–32px). Compare portfólios aprovados: quase todos usam sombras suaves.Módulo 3.1 — Responsividade e mobile-first
Mais da metade dos acessos à web vem de celulares. Site que quebra no celular = candidato eliminado. A ferramenta central é a media query:
/* Abordagem MOBILE-FIRST (padrão do mercado):
escreva o CSS base para telas pequenas... */
.cards {
display: grid;
grid-template-columns: 1fr; /* 1 coluna no celular */
gap: 16px;
}
/* ...e adicione complexidade conforme a tela CRESCE */
@media (min-width: 768px) {
.cards { grid-template-columns: repeat(2, 1fr); } /* tablet */
}
@media (min-width: 1100px) {
.cards { grid-template-columns: repeat(3, 1fr); } /* desktop */
}
Breakpoints comuns (referência, não lei)
| Faixa | Dispositivo típico |
|---|---|
| até 640px | Celulares |
| 641–1023px | Tablets |
| 1024px+ | Notebooks e desktops |
O kit responsivo básico
<!-- Sem esta meta tag no HTML, NADA responsivo funciona no celular -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
img { max-width: 100%; height: auto; } /* imagens nunca estouram o container */
Ver solução
.layout { display: grid; grid-template-columns: 1fr; }
@media (min-width: 900px) {
.layout { grid-template-columns: 250px 1fr; }
}
Mobile-first: base = 1 coluna; desktop = 2 colunas. Exatamente o que esta apostila faz.
Módulo 3.2 — Variáveis CSS (custom properties) e dark mode
Variáveis nativas do CSS permitem definir valores uma vez e reutilizar em todo o projeto:
:root { /* :root = escopo global */
--cor-primaria: #663399;
--cor-texto: #20242F;
--espaco: 16px;
}
.botao {
background: var(--cor-primaria);
padding: var(--espaco);
color: var(--cor-texto);
}
Dark mode em 10 linhas
Como as variáveis podem ser sobrescritas por contexto, trocar o tema inteiro vira trocar meia dúzia de valores:
:root {
--fundo: #ffffff;
--texto: #20242F;
}
/* respeita a preferência do sistema operacional do usuário */
@media (prefers-color-scheme: dark) {
:root {
--fundo: #14161F;
--texto: #E8EAF2;
}
}
body { background: var(--fundo); color: var(--texto); }
Para um botão de alternância manual, basta uma classe no body (body.dark { --fundo: #14161F; }) trocada com 1 linha de JavaScript.
Módulo 3.3 — calc(), clamp(), min() e max()
.sidebar-layout {
width: calc(100% - 280px); /* mistura unidades diferentes */
}
h1 {
/* clamp(MÍNIMO, IDEAL, MÁXIMO): tipografia fluida sem media query */
font-size: clamp(1.8rem, 5vw, 3.5rem);
}
.container {
width: min(90%, 1200px); /* o que for MENOR: container responsivo em 1 linha */
}
Redimensione a janela: eu me adapto!
↑ font-size: clamp(16px, 4vw, 34px) — cresce e encolhe com a tela, dentro dos limites.
Módulo 3.4 — Transições, transforms e animações
transition: animando mudanças de estado
.botao {
background: #663399;
transition: transform .2s ease, box-shadow .2s ease;
}
.botao:hover {
transform: translateY(-3px); /* sobe 3px */
box-shadow: 0 8px 20px rgba(102,51,153,.35);
}
↑ Exatamente o código acima, ao vivo.
transform: mover, girar, escalar
.el { transform: translateX(20px); } /* mover */
.el { transform: rotate(45deg); } /* girar */
.el { transform: scale(1.1); } /* aumentar 10% */
.el { transform: rotate(45deg) scale(1.1); } /* combinar */
@keyframes: animações contínuas
@keyframes girar {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.loading {
animation: girar 3s linear infinite;
/* nome | duração | curva | repetições */
}
↑ O @keyframes girar acima, rodando agora.
transform e opacity — o navegador as processa na GPU sem recalcular o layout. Animar width, height, top ou margin causa travamentos em telas fracas. E respeite @media (prefers-reduced-motion: reduce) para usuários sensíveis a movimento — isso é acessibilidade cobrada em empresas sérias.Módulo 3.5 — CSS moderno que impressiona em entrevista
:has() — o "seletor de pai"
/* estiliza o card QUE CONTÉM uma imagem */
.card:has(img) { padding: 0; }
/* formulário com campo inválido ganha borda vermelha */
form:has(input:invalid) { border-color: red; }
Container queries — responsividade por componente
.sidebar { container-type: inline-size; }
/* o card responde ao tamanho do CONTAINER, não da tela */
@container (min-width: 400px) {
.card { display: flex; }
}
Media queries perguntam "qual o tamanho da tela?"; container queries perguntam "qual o tamanho do espaço onde estou?" — perfeito para componentes reutilizáveis em design systems.
Nesting nativo
.card {
padding: 20px;
.titulo { font-weight: 700; } /* aninhado, sem pré-processador! */
&:hover { box-shadow: 0 4px 24px rgba(0,0,0,.12); }
}
Sim: o CSS incorporou o recurso mais famoso do SCSS (veremos no Módulo 4). Suportado em todos os navegadores modernos desde 2023.
Outros que valem citar
.video { aspect-ratio: 16 / 9; } /* proporção fixa sem hacks */
.thumb { object-fit: cover; } /* imagem preenche sem distorcer */
.grid { place-items: center; } /* atalho p/ centralizar em grid */
.lista { scroll-snap-type: x mandatory; } /* carrossel sem JS */
Módulo 3.6 — Arquitetura CSS: escrevendo código que escala
Saber propriedades te faz passar no teste; saber organizar CSS te faz ser contratado. O problema clássico: projetos crescem, seletores conflitam, ninguém tem coragem de apagar nada.
BEM — Block, Element, Modifier
A convenção de nomenclatura mais pedida em vagas brasileiras:
/* Bloco: o componente independente */
.card { }
/* Elemento: parte do bloco → bloco__elemento */
.card__titulo { }
.card__imagem { }
/* Modificador: variação → bloco--modificador */
.card--destaque { }
.card__botao--desabilitado { }
<article class="card card--destaque">
<img class="card__imagem" src="foto.jpg" alt="Produto">
<h2 class="card__titulo">Título</h2>
</article>
Vantagens: especificidade sempre baixa (só classes), nomes autoexplicativos, zero conflito entre componentes. O código-fonte desta apostila usa BEM (.sidebar__logo, .hero__tag...).
Organização de arquivos
css/
├── base/ /* reset, tipografia, variáveis */
├── components/ /* botao.css, card.css, navbar.css */
├── layout/ /* header.css, footer.css, grid.css */
└── pages/ /* home.css, contato.css */
Módulo 3.7 — Acessibilidade e performance
Acessibilidade (a11y) no CSS
- Nunca remova o focus sem substituir:
:focus { outline: none; }sozinho quebra a navegação por teclado. Se remover, forneça um:focus-visiblecustomizado. - Contraste mínimo 4.5:1 entre texto e fundo (padrão WCAG AA). Teste no próprio DevTools: inspecione o texto e veja o índice de contraste.
- Fontes em
remrespeitam o zoom de texto configurado pelo usuário. prefers-reduced-motionpara desligar animações de quem enjoa com movimento.
.botao:focus-visible {
outline: 3px solid #663399;
outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
* { animation: none !important; transition: none !important; }
}
Performance
- Anime só
transformeopacity(Módulo 3.4); - Evite seletores profundos como
div ul li a span— além de lentos, são frágeis; - Minifique o CSS em produção (ferramentas de build fazem isso automaticamente);
- Carregue fontes com
font-display: swappara o texto aparecer antes da fonte baixar.
Módulo 4.1 — O que é Sass/SCSS
Sass é um pré-processador: uma linguagem que compila para CSS. Você escreve num arquivo .scss com superpoderes (variáveis com lógica, funções, loops, módulos) e uma ferramenta converte para o CSS que o navegador entende.
SCSS é a sintaxe moderna do Sass — todo CSS válido já é SCSS válido, então a curva de aprendizado é suave.
Instalando e compilando
# requer Node.js instalado
npm install -g sass
# compila uma vez
sass style.scss style.css
# modo watch: recompila a cada salvamento (use este no dia a dia)
sass --watch scss/:css/
Em projetos reais com React/Vue/Vite, a compilação é automática: basta instalar sass como dependência e importar o arquivo .scss.
Módulo 4.2 — Variáveis, nesting e partials
Variáveis com $
$roxo: #663399;
$espaco: 16px;
.botao {
background: $roxo;
padding: $espaco ($espaco * 2); // SCSS faz MATEMÁTICA com variáveis
border: 1px solid darken($roxo, 15%); // e tem funções de cor embutidas
}
Diferença para variáveis CSS: as do SCSS são resolvidas na compilação (viram valores fixos); as do CSS vivem no navegador e podem mudar em tempo real (por isso dark mode usa variáveis CSS). Times maduros usam as duas juntas.
Nesting (aninhamento)
.navbar {
display: flex;
gap: 24px;
a {
color: white;
text-decoration: none;
&:hover { color: $roxo; } // & = o seletor pai (.navbar a:hover)
&.ativo { font-weight: bold; } // .navbar a.ativo
}
}
// & também encurta BEM:
.card {
&__titulo { font-size: 1.2rem; } // vira .card__titulo
&--destaque { border: 2px solid $roxo; } // vira .card--destaque
}
Partials e @use: dividindo em arquivos
// _variaveis.scss (o underscore indica: "não compile sozinho")
$roxo: #663399;
// _botoes.scss
@use 'variaveis' as v;
.botao { background: v.$roxo; }
// main.scss — o único que vira CSS final
@use 'variaveis';
@use 'botoes';
@use 'navbar';
@use substituiu o antigo @import (deprecado). Se encontrar @import num projeto legado, saiba ler os dois.
Módulo 4.3 — Mixins, funções, @extend e loops
Mixins: blocos reutilizáveis (com parâmetros!)
@mixin flex-center($direcao: row) {
display: flex;
justify-content: center;
align-items: center;
flex-direction: $direcao;
}
@mixin mobile {
@media (max-width: 640px) { @content; }
}
.hero {
@include flex-center(column);
@include mobile {
padding: 16px; // injetado dentro da media query
}
}
O mixin de breakpoint é o padrão de mercado: centraliza os breakpoints num lugar só e deixa as media queries legíveis.
Funções
@function rem($px) {
@return calc($px / 16) * 1rem;
}
h1 { font-size: rem(32); } // → 2rem
@extend e placeholders
%botao-base {
padding: 12px 28px;
border-radius: 8px;
font-weight: 700;
}
.botao-primario { @extend %botao-base; background: $roxo; }
.botao-secundario { @extend %botao-base; background: transparent; border: 2px solid $roxo; }
Loops: gerando classes utilitárias
@for $i from 1 through 5 {
.mt-#{$i} { margin-top: $i * 8px; }
}
// gera .mt-1 {margin-top: 8px} até .mt-5 {margin-top: 40px}
$cores: (primaria: #663399, sucesso: #2B8A3E, erro: #E8590C);
@each $nome, $valor in $cores {
.texto-#{$nome} { color: $valor; }
}
Módulo 4.4 — SCSS no mercado hoje: o cenário honesto
Vale calibrar expectativas para não estudar no escuro:
- SCSS ainda aparece muito em vagas — especialmente em empresas com projetos Angular, WordPress, Vue e bases de código com alguns anos. Saber ler e escrever SCSS é requisito frequente.
- O CSS moderno absorveu recursos do Sass: variáveis, nesting e funções matemáticas hoje são nativos. Projetos novos às vezes escolhem CSS puro + variáveis.
- Tailwind CSS cresceu muito como alternativa (classes utilitárias direto no HTML). Muitas vagas React pedem Tailwind em vez de SCSS.
Estratégia recomendada: domine CSS puro profundamente (é a base de tudo), saiba SCSS o suficiente para trabalhar em qualquer projeto que o use (este módulo cobre 90% do uso real), e aprenda Tailwind quando for entrar no ecossistema React.
@use ainda não têm equivalente nativo — além de bases de código existentes que precisam de manutenção. Mostra que você entende trade-offs, não só sintaxe..menu { background: #663399; }
.menu a { color: white; padding: 8px 16px; }
.menu a:hover { background: #4B2570; }
.menu a.ativo { font-weight: bold; }
Ver solução
$roxo: #663399;
@mixin hover-escuro {
&:hover { background: darken($roxo, 15%); }
}
.menu {
background: $roxo;
a {
color: white;
padding: 8px 16px;
@include hover-escuro;
&.ativo { font-weight: bold; }
}
}
Módulo 5.1 — Projeto: Card de perfil
Primeiro projeto de portfólio: um card de perfil como os do LinkedIn. Treina box model, border-radius, sombras, flexbox e o duo relative/absolute.
Ana Ferreira
Desenvolvedora Front-end
Estrutura HTML
<article class="card">
<div class="card__topo"></div>
<div class="card__corpo">
<div class="card__avatar">👩💻</div>
<p class="card__nome">Ana Ferreira</p>
<p class="card__cargo">Desenvolvedora Front-end</p>
<button class="card__botao">Conectar</button>
</div>
</article>
CSS comentado
.card {
max-width: 320px;
background: #fff;
border-radius: 14px;
overflow: hidden; /* o topo colorido respeita os cantos arredondados */
box-shadow: 0 4px 24px rgba(32,36,47,.12);
}
.card__topo {
height: 80px;
background: linear-gradient(135deg, #663399, #9B59D0);
}
.card__corpo {
padding: 0 20px 20px;
text-align: center;
}
.card__avatar {
width: 72px;
height: 72px;
border-radius: 50%;
background: #FFE066;
border: 4px solid #fff;
margin: -36px auto 8px; /* margem NEGATIVA: metade do avatar invade o topo */
display: flex;
align-items: center;
justify-content: center;
font-size: 30px;
}
.card__nome { font-weight: 700; font-size: 18px; margin: 0; }
.card__cargo { color: #5A6072; font-size: 14px; margin: 2px 0 14px; }
position: absolute; (b) faça o card subir 4px no hover com transição suave; (c) adicione uma linha de estatísticas (posts · seguidores · conexões) usando flexbox com justify-content: space-around.
Módulo 5.2 — Projeto: Navbar responsiva
Toda entrevista prática tem uma navbar. Esta versão usa zero JavaScript: o menu mobile abre com o truque do checkbox invisível — demonstra domínio de seletores.
<nav class="nav">
<span class="nav__logo">MeuSite</span>
<input type="checkbox" id="menu-toggle" class="nav__check">
<label for="menu-toggle" class="nav__hamburguer">☰</label>
<ul class="nav__links">
<li><a href="#">Home</a></li>
<li><a href="#">Projetos</a></li>
<li><a href="#">Contato</a></li>
</ul>
</nav>
/* Mobile-first: menu escondido, hambúrguer visível */
.nav {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
padding: 16px 24px;
background: #20242F;
}
.nav__logo { color: #fff; font-weight: 700; }
.nav__check { display: none; } /* o checkbox em si fica invisível */
.nav__hamburguer { color: #fff; font-size: 24px; cursor: pointer; }
.nav__links {
display: none; /* fechado por padrão */
width: 100%;
list-style: none;
margin: 0; padding: 0;
}
/* A MÁGICA: checkbox marcado + irmão seguinte = menu aberto */
.nav__check:checked ~ .nav__links { display: block; }
.nav__links a {
display: block;
color: #C4C8D6;
text-decoration: none;
padding: 12px 0;
}
.nav__links a:hover { color: #FFE066; }
/* Desktop: esconde o hambúrguer, mostra os links em linha */
@media (min-width: 768px) {
.nav__hamburguer { display: none; }
.nav__links {
display: flex !important; /* sempre visível no desktop */
width: auto;
gap: 28px;
}
.nav__links a { padding: 0; }
}
~), a pseudo-classe :checked, mobile-first e o trade-off "CSS puro vs JavaScript". Depois, refaça a versão com JS e um botão <button aria-expanded> — a versão com botão é mais acessível para leitores de tela, e saber comparar as duas é ponto extra.Módulo 5.3 — Projeto final: Landing page completa
O projeto que vai para o topo do portfólio. Monte uma landing page de um produto fictício (app, cafeteria, academia — escolha algo de que você goste) com estas seções:
| Seção | Técnicas que ela demonstra |
|---|---|
| 1. Navbar fixa | position: sticky, flexbox, projeto 5.2 |
| 2. Hero (título + botão CTA) | min-height: 100vh, centralização, clamp() no título, gradiente |
| 3. Grade de 3 benefícios | Grid com auto-fit/minmax, cards com sombra e hover |
| 4. Depoimentos | Flexbox, border-radius: 50% nos avatares, ::before com aspas decorativas |
| 5. Formulário de contato | Estilização de inputs, :focus-visible, estados :invalid |
| 6. Footer | Grid de colunas, variáveis CSS para o tema escuro da seção |
Esqueleto para começar
:root {
--primaria: #663399; /* troque pela paleta do SEU tema */
--escuro: #20242F;
--claro: #FBFAF6;
--espaco-secao: clamp(48px, 8vw, 110px);
}
* { box-sizing: border-box; margin: 0; }
body { font-family: system-ui, sans-serif; line-height: 1.6; color: var(--escuro); }
section { padding: var(--espaco-secao) 24px; }
.container { width: min(90%, 1100px); margin: 0 auto; }
.hero {
min-height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
background: linear-gradient(135deg, var(--primaria), #9B59D0);
color: #fff;
}
.hero h1 { font-size: clamp(2rem, 6vw, 4rem); }
Critérios de "pronto para o portfólio"
- ☐ Funciona de 320px (celular pequeno) a 1920px sem quebrar nem gerar barra de rolagem horizontal;
- ☐ Todos os estados interativos:
:hover,:focus-visible,:active; - ☐ Nomenclatura BEM consistente;
- ☐ Cores e espaçamentos vindos de variáveis CSS (nada de valores mágicos repetidos);
- ☐ Contraste de texto verificado no DevTools;
- ☐ Publicada online (GitHub Pages, Netlify ou Vercel — todos gratuitos).
Desafio extra: refaça o CSS da landing em SCSS, com _variaveis.scss, _mixins.scss (incluindo o mixin de breakpoint do Módulo 4.3) e um partial por seção. Suba as duas versões no GitHub — isso vira assunto de entrevista.
Módulo 6.1 — O que as vagas realmente pedem
Analisando vagas de front-end júnior no Brasil, o padrão de requisitos envolvendo CSS é consistente:
| Requisito da vaga | Onde você aprendeu nesta apostila |
|---|---|
| "HTML5 e CSS3 sólidos" | Módulos 1 e 2 inteiros |
| "Layouts responsivos / mobile-first" | 3.1 |
| "Flexbox e Grid" | 2.4 e 2.5 |
| "Sass/SCSS ou Less" | Módulo 4 |
| "Metodologias como BEM" | 3.6 |
| "Acessibilidade (WCAG)" | 3.7 |
| "Pixel perfect a partir do Figma" | Prática dos projetos do Módulo 5 |
"Pixel perfect" merece explicação: significa reproduzir fielmente um layout desenhado no Figma. Treine pegando designs gratuitos da comunidade do Figma (ou desafios do Frontend Mentor) e reproduzindo em código — é o formato mais comum de teste técnico júnior.
Módulo 6.2 — Perguntas de entrevista (com respostas)
Nível júnior
1. Explique o box model.
Todo elemento é uma caixa com content, padding, border e margin. Com box-sizing: border-box, o width declarado passa a incluir padding e borda, tornando o layout previsível.
2. Qual a diferença entre margin e padding?
Padding é espaço interno (entre conteúdo e borda; herda a cor de fundo do elemento). Margin é espaço externo (entre o elemento e os vizinhos; sempre transparente).
3. Diferença entre display:none e visibility:hidden?
display:none remove o elemento do fluxo — o espaço some. visibility:hidden só o torna invisível — o espaço continua reservado.
4. Diferença entre em e rem?
rem é relativo à fonte do elemento raiz (previsível); em é relativo à fonte do pai (acumula em aninhamentos). O mercado padroniza rem.
5. Como centralizar uma div?
Três formas: flexbox (display:flex; justify-content:center; align-items:center), grid (display:grid; place-items:center) e, para centralização só horizontal de bloco com largura definida, margin: 0 auto.
Nível pleno
6. Explique especificidade e por que evitar !important.
Especificidade é o placar (IDs, classes, elementos) que decide qual regra vence. !important ignora esse sistema, criando regras impossíveis de sobrescrever sem outro !important — uma corrida armamentista. A solução correta é manter especificidade baixa e consistente (só classes, como no BEM).
7. Flexbox vs Grid: quando usar cada um?
Flexbox para uma dimensão (alinhamento de itens em linha ou coluna: menus, botões); Grid para duas (estrutura da página: galerias, dashboards). Na prática, Grid para o esqueleto e Flexbox dentro dos componentes.
8. O que são pseudo-classes e pseudo-elementos?
Pseudo-classes (:hover, :focus, :nth-child) selecionam estados ou posições de elementos existentes. Pseudo-elementos (::before, ::after, ::first-line) criam ou estilizam partes que não existem no HTML.
9. Como você faria dark mode?
Design tokens em variáveis CSS no :root, sobrescritos por @media (prefers-color-scheme: dark) para respeitar o sistema, mais uma classe no body para alternância manual persistida em localStorage.
10. Quais propriedades são mais baratas de animar e por quê?
transform e opacity: são compostas na GPU sem disparar recálculo de layout (reflow) nem repintura, mantendo 60fps. Animar width, height ou top força reflow a cada frame.
11. Por que usar SCSS se o CSS moderno tem variáveis e nesting?
Mixins parametrizados, funções próprias, loops e o sistema de módulos @use ainda não têm equivalente nativo — e há muitas bases de código SCSS em manutenção. Mas para projetos novos e simples, CSS puro moderno pode bastar; a escolha é um trade-off de equipe.
12. O que é a cascata do CSS?
O algoritmo que resolve conflitos entre regras, considerando origem (autor > navegador), especificidade do seletor e, em empate, ordem no código (a última vence). Herança complementa: propriedades de texto descem para os filhos.
Módulo 6.3 — Checklist de portfólio que gera entrevista
- 3 projetos bem-feitos > 10 medianos. Sugestão: os três desta apostila, evoluídos — card de perfil, navbar/página institucional e a landing page completa.
- Tudo publicado online com link clicável (GitHub Pages, Netlify ou Vercel). Recrutador não clona repositório.
- README caprichado em cada repositório: screenshot, link ao vivo, técnicas usadas ("Grid com auto-fit, BEM, dark mode com variáveis CSS") e o que você aprendeu.
- Responsivo sem exceção. O recrutador vai abrir no celular. Se quebrar, acabou.
- Um projeto reproduzindo design real (Frontend Mentor tem designs gratuitos com nível de dificuldade) — prova que você faz "pixel perfect".
- Commits em português ou inglês consistentes e frequentes — mostra processo, não só resultado.
- Acessibilidade citada explicitamente no README: contraste testado, navegação por teclado, reduced-motion. Pouquíssimos juniores fazem isso.
Módulo 6.4 — Próximos passos na carreira
Com CSS e SCSS dominados, a trilha natural de front-end segue assim:
- JavaScript — a próxima linguagem obrigatória: interatividade, DOM, eventos, fetch;
- Git e GitHub a fundo — branches, pull requests, resolução de conflitos (usado todo dia em equipe);
- Um framework — React domina as vagas no Brasil; Vue e Angular também têm mercado;
- Tailwind CSS — quando entrar no ecossistema React, aprenda a abordagem utility-first;
- TypeScript — cada vez mais presente até em vagas júnior.
E continue praticando CSS: Frontend Mentor (desafios com design pronto), CSS Battle (golfe de CSS, ótimo para seletores) e os guias da MDN Web Docs — a documentação oficial de referência, em português inclusive.
Fim da apostila — e começo da prática. 🚀
Lembre-se: esta página inteira foi construída com as técnicas que ela ensina.
Abra o código-fonte (Ctrl+U), inspecione com o DevTools (F12) e use-a como material de estudo duplo.