[ ] Pasta site-evento/ com as cinco páginas em HTML semântico da Unidade 1 (index.html, programacao.html, inscricao.html, palestrantes.html, contato.html), validadas no W3C.
[ ] site-evento/css/estilo.css criado na Aula 06, com o reset box-sizing: border-box, o bloco :root de variáveis e a folha organizada na ordem recomendada (reset → variáveis → base → layout → componentes → utilitários → media queries).
[ ] VS Code com a extensão Live Server e um navegador com DevTools (Chrome ou Firefox).
[ ] Revisar da Aula 06: especificidade de seletores, display: block versus display: inline, o modelo de caixa (margin, border, padding) e var(--nome).
Na aula passada você estilizou o site do evento: sistema de design em variáveis, tipografia, cores, botões e tabela. Mas as páginas ainda são uma pilha de blocos de cima para baixo — o cabeçalho não fica ao lado do logo, os cartões de palestra não formam uma grade e o rodapé sobe quando a página tem pouco conteúdo. Hoje você aprende as duas ferramentas que resolvem isso — Flexbox e Grid — e constrói o esqueleto de layout definitivo do site, com um menu de navegação que qualquer pessoa consegue usar.
1.1 O que o navegador faz quando você não diz nada¶
Antes de qualquer CSS de layout, o navegador já tem um plano: o fluxo normal. Elementos de bloco (div, p, section, h1) são empilhados de cima para baixo, cada um ocupando toda a largura disponível. Elementos em linha (a, strong, span, img) são dispostos lado a lado, da esquerda para a direita, quebrando linha quando falta espaço — exatamente como as palavras de um parágrafo.
Pense no fluxo normal como a água escorrendo por uma calha: cada caixa cai na primeira posição livre. Tudo o que você vai aprender hoje — position, Flexbox, Grid — é uma forma de desviar a água: tirar um elemento do fluxo ou trocar as regras de como os filhos de um contêiner se organizam.
🧠 Você sabia?
Toda vez que o navegador precisa recalcular a posição e o tamanho das caixas, ele faz um reflow (ou layout). Mudar a largura de um elemento no topo da página pode obrigar o navegador a recalcular a posição de todos os elementos abaixo dele — em uma página grande, isso custa milissegundos que se transformam em travadas visíveis. É por isso que, na Aula 09, você vai aprender a animar só propriedades que não disparam reflow. Por enquanto, guarde a ideia: layout é a etapa cara do desenho de uma página.
1.2 position: cinco maneiras de dizer "fique aqui"¶
A propriedade position define em relação a quê um elemento é posicionado e se ele ainda ocupa espaço no fluxo. As propriedades top, right, bottom e left só têm efeito quando position é diferente de static.
Exemplo — os cinco valores lado a lado
CSS
.a{position:static;}/* padrão; ignora top/right/bottom/left */.b{position:relative;top:10px;left:20px;}/* desloca-se da própria posição original */.c{position:absolute;top:0;right:0;}/* canto do ancestral posicionado mais próximo */.d{position:fixed;bottom:20px;right:20px;}/* preso à janela; não rola com a página */.e{position:sticky;top:0;}/* normal até encostar no topo; então gruda */
Valor
Referência de posicionamento
Ocupa espaço no fluxo?
static
Nenhuma — segue o fluxo normal
Sim
relative
A própria posição original
Sim (o espaço original é mantido, mesmo deslocado)
absolute
O ancestral posicionado mais próximo (ou o <html>)
Não — sai do fluxo
fixed
A janela do navegador (viewport)
Não — sai do fluxo
sticky
Fluxo normal até atingir o limite (top, bottom); depois, o contêiner de rolagem
Sim
A regra de ouro do absolute. Um elemento absolute procura, subindo na árvore, o ancestral mais próximo cujo position seja diferente de static. Se não encontrar nenhum, ele se posiciona em relação à página inteira — e vai parar no canto do documento, longe de onde você queria. Por isso a receita clássica é: position: relative no pai (que não se move, porque sem top/left o relative não desloca nada) e position: absolute no filho.
No site do evento, é assim que o selo "Esgotado" fica preso no canto do cartão de um minicurso:
site-evento/css/estilo.css — trecho
CSS
.cartao{position:relative;/* vira a referência do selo, sem se mover */}.cartao__selo{position:absolute;/* sai do fluxo e ancora no cartão */top:8px;right:8px;}
sticky merece atenção especial. Ele é o híbrido: o elemento rola normalmente com a página até que a distância definida (top: 0) seja atingida; a partir daí, ele "gruda" e a página continua rolando por baixo. É o comportamento perfeito para um cabeçalho: não rouba espaço no topo quando a página carrega, mas fica sempre à mão. Duas condições para funcionar: declarar top (ou bottom) e nenhum ancestral com overflow diferente de visible — você vai reencontrar essa segunda condição na tabela de erros comuns.
💡 Dicafixed e sticky parecem iguais no cabeçalho, mas diferem no resto: fixed sai do fluxo (o conteúdo abaixo sobe e fica escondido atrás do cabeçalho, obrigando você a compensar com padding-top no body); sticky continua ocupando o espaço original. Prefira sticky para cabeçalhos.
Quando dois elementos posicionados se sobrepõem, quem fica na frente? Por padrão, o que vem depois no HTML. z-index muda isso: valores maiores ficam à frente. Só funciona em elementos com position diferente de static (e em itens de Flexbox e Grid).
⚠️ Atenção
Evite z-index: 9999. Quando cada componente "grita mais alto" que o anterior, ninguém sabe mais quem está na frente de quem. Defina uma escala do projeto e documente-a na folha de estilo. No site do evento: 100 para o cabeçalho fixo, 900 para sobreposições escuras, 1000 para modais e para o link de salto.
🔎 Por baixo do capôz-index não é uma escala global. Todo elemento posicionado com z-index diferente de auto cria um contexto de empilhamento: os filhos dele só competem entre si, e o grupo inteiro é comparado com os vizinhos usando o z-index do pai. É por isso que, às vezes, um z-index: 9999 "não funciona": o elemento está dentro de um contexto com z-index: 1, e o contexto inteiro está atrás de outro com z-index: 2. opacity menor que 1, transform e filter também criam contextos de empilhamento — lembre-se disso na Aula 09.
float foi criado com um único propósito: fazer texto envolver uma imagem, como em uma revista. Como durante mais de dez anos não existia nada melhor, a comunidade usou float para construir colunas, menus e páginas inteiras — com gambiarras como clearfix e contêineres que colapsavam. Hoje não use float para layout: Flexbox e Grid resolvem tudo isso de forma previsível. Ainda é válido para o caso original:
CSS
figure{float:left;margin:016px16px0;}/* texto envolve a figura */.limpa{clear:both;}/* próximo elemento não envolve nada */
Você vai encontrar float em código antigo, em tutoriais desatualizados e em respostas de fórum. Saiba ler; não escreva.
1.5 overflow: o que acontece quando o conteúdo não cabe¶
CSS
overflow:visible;/* padrão: o conteúdo transborda e aparece fora da caixa */overflow:hidden;/* corta o excesso */overflow:auto;/* barra de rolagem só quando precisar */overflow:scroll;/* barra sempre visível */overflow-x:auto;/* controle por eixo */overflow-y:hidden;
Um uso legítimo no site do evento: uma tabela de programação larga, dentro de um contêiner com overflow-x: auto, rola horizontalmente no celular em vez de estourar a página inteira.
🔬 Investigue
Abra index.html com o Live Server e o DevTools (F12). No painel Elements, selecione o <header> e, na aba Styles, adicione position: sticky; top: 0; clicando no bloco element.style. Role a página: o cabeçalho gruda. Agora troque para position: fixed: veja o conteúdo "pular" para cima, porque o cabeçalho saiu do fluxo e deixou de ocupar espaço. Por fim, adicione overflow-x: hidden ao <body> com o sticky de volta — e observe que o cabeçalho para de grudar. Você acabou de encontrar o bug de sticky mais comum da web.
Flexbox distribui os filhos de um contêiner ao longo de um eixo — uma linha ou uma coluna — e resolve, com poucas propriedades, o que antes exigia truques: alinhar verticalmente, distribuir espaço sobrando, fazer itens crescerem ou encolherem, mudar a ordem visual.
CSS
.contêiner{display:flex;}
Só essa linha já transforma todos os filhos diretos em flex items e os coloca lado a lado. Os netos não são afetados — Flexbox age em um nível só. Isso importa: se você quiser um Flexbox dentro de um item, o item precisa ser, ele mesmo, um contêiner display: flex.
Com flex-direction: column, os eixos trocam de papel: o principal passa a ser vertical. Todas as propriedades a seguir são definidas em relação a esses eixos, não em relação a "horizontal" e "vertical". Essa é a fonte da confusão mais comum com Flexbox — e a razão de justify-content alinhar horizontalmente em uma linha, mas verticalmente em uma coluna.
.contêiner{display:flex;flex-direction:row;/* row | row-reverse | column | column-reverse */flex-wrap:wrap;/* nowrap (padrão) | wrap | wrap-reverse */justify-content:center;/* distribui no EIXO PRINCIPAL *//* flex-start | flex-end | center | space-between | space-around | space-evenly */align-items:center;/* alinha no EIXO TRANSVERSAL *//* stretch (padrão) | flex-start | flex-end | center | baseline */align-content:center;/* alinha as LINHAS entre si (só com wrap e várias linhas) */gap:16px;/* espaço entre itens — use isto, não margin */row-gap:16px;column-gap:24px;}
Valor de justify-content
Resultado
flex-start
Todos encostados no início do eixo (padrão)
flex-end
Todos encostados no fim
center
Agrupados no centro
space-between
Primeiro na ponta, último na ponta, o resto distribuído por igual
space-around
Espaço igual em volta de cada item (as bordas ficam com metade)
space-evenly
Espaços exatamente iguais, inclusive nas bordas
Repare em align-items: stretch, o padrão: os itens esticam para ocupar toda a altura do contêiner. É por isso que, em uma linha de cartões flex, todos ficam com a mesma altura sem nenhum esforço — algo que era quase impossível com float.
A centralização perfeita. Centralizar um elemento nos dois eixos foi, por vinte anos, um dos problemas mais frustrantes do CSS. Hoje são três linhas:
CSS
.centro{display:flex;justify-content:center;/* eixo principal */align-items:center;/* eixo transversal */}
🧠 Você sabia?
O primeiro rascunho do Flexbox é de 2009 — mas ele só se tornou utilizável em todos os navegadores por volta de 2015. Foram três sintaxes diferentes no caminho (display: box, depois display: flexbox, por fim display: flex), cada uma com prefixos de fornecedor (-webkit-, -ms-), e um Internet Explorer que implementou a versão intermediária e nunca atualizou. Se você encontrar display: -webkit-box em código antigo, é um fóssil dessa história. A lição: uma especificação só vira ferramenta quando todos os navegadores concordam — e isso leva tempo.
As propriedades do contêiner organizam o conjunto; as dos itens dizem como cada um reage ao espaço disponível.
CSS
.item{flex-grow:1;/* fator de crescimento quando sobra espaço (padrão 0: não cresce) */flex-shrink:1;/* fator de encolhimento quando falta espaço (padrão 1: encolhe) */flex-basis:200px;/* tamanho inicial antes de distribuir (padrão auto: o tamanho do conteúdo) */flex:1;/* atalho = flex: 1 1 0 — todos os itens com o mesmo tamanho */flex:00250px;/* largura fixa: não cresce, não encolhe */flex:11280px;/* começa com 280px, cresce e encolhe conforme o espaço */align-self:flex-end;/* sobrescreve align-items só neste item */order:2;/* muda a ordem visual (padrão 0; menores vêm primeiro) */}
Como ler flex: 1 1 280px: "comece com 280 px; se sobrar espaço, cresça na proporção 1; se faltar, encolha na proporção 1". Quando todos os irmãos têm flex: 1, o espaço é dividido igualmente. Quando um tem flex: 2 e os outros flex: 1, ele recebe o dobro do espaço sobrando — não o dobro do tamanho total.
⚠️ Atençãoorder muda apenas a ordem visual, não a ordem do DOM. Quem navega com Tab ou com um leitor de tela continua seguindo a ordem do HTML — e, se a tela mostra "Contato" antes de "Início" mas o foco vai na ordem contrária, a experiência fica confusa. Use order com parcimônia e nunca para inverter a sequência lógica de navegação.
/* 1. Barra de navegação: logo à esquerda, menu à direita, tudo alinhado no centro */.cabecalho__interno{display:flex;justify-content:space-between;align-items:center;padding:16px32px;}/* 2. Menu horizontal com espaçamento uniforme */.menu{display:flex;gap:24px;list-style:none;}/* 3. Linha de cartões que quebra sozinha quando falta espaço */.cartoes-flex{display:flex;flex-wrap:wrap;gap:24px;}.cartoes-flex.cartao{flex:11280px;/* mínimo 280px; cresce para preencher; quebra linha quando não couber */}/* 4. Rodapé sempre no fim da tela, mesmo com pouco conteúdo */body{display:flex;flex-direction:column;min-height:100vh;}main{flex:1;/* o main absorve todo o espaço sobrando; o rodapé é empurrado para baixo */}
O padrão 4 resolve um problema clássico do site do evento: a página contato.html tem pouco conteúdo, e o rodapé ficava flutuando no meio da tela. Com body em coluna e main { flex: 1 }, o rodapé vai para o fim da janela — e, quando a página cresce, ele desce junto.
🔬 Investigue
No DevTools, painel Elements, todo elemento com display: flex ganha um selo cinza escrito flex ao lado da tag. Clique nele: o navegador desenha o eixo principal, o contorno de cada item e os espaços de gap. Agora abra a aba Layout (Chrome) ou o painel Flexbox (Firefox): você pode ligar o overlay de vários contêineres ao mesmo tempo e ver, ao vivo, o que justify-content: space-between está fazendo com o espaço. Troque o valor na aba Styles e observe o desenho mudar.
Flexbox pensa em uma fila. Grid pensa em uma tabela invisível: você declara colunas e linhas, e os filhos ocupam as células. É a ferramenta certa para a estrutura geral de uma página — cabeçalho, lateral, conteúdo, rodapé — e para qualquer coisa que precise alinhar nos dois eixos, como uma galeria.
CSS
.grade{display:grid;grid-template-columns:200px1fr200px;/* três colunas: fixa, elástica, fixa */grid-template-rows:auto1frauto;/* três linhas: conteúdo, elástica, conteúdo */gap:20px;}
A unidade fr (fraction) representa uma fração do espaço que sobra depois de descontar tamanhos fixos e gaps. Em um contêiner de 1000 px com 200px 1fr 200px e gap: 20px, sobram 1000 − 200 − 200 − 40 = 560 px para a coluna do meio. Com 1fr 2fr, o espaço livre é dividido em três partes: uma para a primeira coluna, duas para a segunda.
grid-template-columns:200px200px200px;/* três fixas */grid-template-columns:1fr1fr1fr;/* três iguais e elásticas */grid-template-columns:repeat(3,1fr);/* idem, abreviado */grid-template-columns:250px1fr;/* lateral fixa + conteúdo elástico */grid-template-columns:repeat(auto-fit,minmax(250px,1fr));/* responsivo sem media query */
💡 Dica
A linha repeat(auto-fit, minmax(250px, 1fr)) é uma das mais poderosas do CSS moderno. Leia-a assim: "crie quantas colunas couberem (auto-fit), cada uma com no mínimo 250 px e no máximo uma fração igual do espaço (minmax(250px, 1fr))". Em uma janela de 1100 px cabem quatro colunas; em 800 px, três; em um celular, uma. A grade se reorganiza sozinha — sem nenhuma media query. É assim que os cartões de programação e de palestrantes do site do evento vão se comportar.
auto-fit ou auto-fill? Os dois criam quantas colunas couberem. A diferença aparece quando há poucos itens: auto-fill mantém as colunas vazias (três cartões em uma grade de cinco colunas ficam encolhidos à esquerda); auto-fit colapsa as faixas vazias e deixa os itens existentes esticarem para ocupar a largura toda. Para cartões, quase sempre você quer auto-fit.
Grid numera as linhas-guia (as divisórias), não as células. Uma grade de três colunas tem quatro linhas-guia verticais: 1, 2, 3 e 4.
CSS
.item{grid-column:1/3;/* da linha-guia 1 até a 3 — ocupa duas colunas */grid-column:span2;/* ocupa duas colunas a partir de onde estiver */grid-row:2/4;/* da linha-guia 2 até a 4 — ocupa duas linhas */grid-area:2/1/4/3;/* linha-início / coluna-início / linha-fim / coluna-fim */}
Itens sem posição explícita são colocados automaticamente na próxima célula livre, na ordem do HTML. Isso é o que faz auto-fit funcionar sem que você precise posicionar cartão por cartão.
3.4 Áreas nomeadas — o layout desenhado no código¶
Números de linha-guia funcionam, mas ninguém lê grid-area: 2 / 1 / 4 / 3 e visualiza a página. Áreas nomeadas resolvem isso: você desenha o layout com palavras.
Cada string é uma linha da grade; cada palavra, uma célula. Repetir o nome em células vizinhas faz a área se estender (o cabeçalho ocupa as duas colunas). Um ponto (.) marca uma célula vazia. Para reorganizar tudo no celular, basta redesenhar as áreas dentro de uma media query — uma coluna só, cada área em uma linha — sem tocar no HTML. Você fará exatamente isso na Aula 08.
As propriedades de alinhamento têm os mesmos nomes do Flexbox, mas com uma camada a mais: alinhar os itens dentro das células e alinhar a grade inteira dentro do contêiner.
CSS
.grade{justify-items:center;/* cada item, horizontalmente, dentro da sua célula */align-items:center;/* cada item, verticalmente, dentro da sua célula */place-items:center;/* atalho: align-items + justify-items */justify-content:center;/* a grade inteira, horizontalmente, no contêiner */align-content:center;/* a grade inteira, verticalmente, no contêiner */}
📌 Vale gravar
Em Grid, justify-* sempre se refere ao eixo horizontal (colunas) e align-* ao vertical (linhas). Em Flexbox, justify-content segue o eixo principal, que muda com flex-direction. Essa diferença cai no dia a dia — vale gravar.
🔬 Investigue
Selecione no DevTools qualquer elemento com display: grid; ele ganha um selo grid. Clique nele e vá à aba Layout: ative "Show line numbers" e "Show area names". O navegador desenha as linhas-guia numeradas e escreve o nome de cada área por cima da página. Redimensione a janela com o overlay ligado e veja auto-fit criando e removendo colunas. Esse overlay vai economizar horas de tentativa e erro — use-o sempre que um item cair na célula errada.
A pergunta certa não é "qual é melhor", e sim "quantas dimensões o problema tem".
Use Flexbox quando
Use Grid quando
O layout é uma linha ou uma coluna
Você precisa controlar linhas e colunas
O tamanho dos itens (conteúdo) define a distribuição
O contêiner define a estrutura, e o conteúdo se encaixa
Barra de navegação, grupo de botões, cartões em linha, campo de busca com botão
Estrutura da página, galerias, dashboards, formulários em colunas
Alinhar coisas dentro de um componente
Posicionar os componentes na página
Eles não competem — se combinam. A arquitetura padrão de um site hoje é: Grid para a estrutura da página (onde ficam cabeçalho, lateral, conteúdo, rodapé) e Flexbox para o interior de cada componente (o que há dentro do cabeçalho, de um cartão, de um formulário). É assim que o site do evento vai ficar ao fim desta aula.
Dois testes rápidos para decidir:
Você consegue descrever o layout com uma frase que tenha "ao lado" ou "abaixo", mas não os dois? Flexbox. ("Logo ao lado do menu"; "campos empilhados abaixo do outro".)
Você precisa que a segunda linha se alinhe com a primeira? Grid. (Uma galeria em que as colunas precisam bater; um formulário em que os rótulos alinham nas duas linhas.)
O menu é o componente que mais concentra erros de acessibilidade em projetos reais. Ele também é a primeira coisa que todo visitante toca. Vale construí-lo com cuidado.
<headerclass="cabecalho"><divclass="container cabecalho__interno"><ahref="index.html"class="logo"><imgsrc="img/logo-sasi.svg"alt="Página inicial — Semana Acadêmica de Sistemas de Informação"></a><navaria-label="Principal"><ulclass="menu"><li><ahref="index.html"aria-current="page">Início</a></li><li><ahref="programacao.html">Programação</a></li><li><ahref="palestrantes.html">Palestrantes</a></li><li><ahref="contato.html">Contato</a></li><li><ahref="inscricao.html"class="menu__cta">Inscreva-se</a></li></ul></nav></div></header>
⚠️ Atenção
Este cabeçalho substitui o <header id="topo"> das Aulas 02 a 06 (logo solto, <h1> do site, parágrafo de local e <nav> sem classe). Apague o bloco antigo inteiro nas cinco páginas e cole este no lugar. Junto com ele vão embora duas coisas: o parágrafo "Três noites de outubro · Auditório Central", que passa a viver no herói da página inicial e no rodapé, e o <h1> do cabeçalho — a partir de hoje o <h1> é o título da página, dentro do <main> (o que era <h2>Programação</h2> vira <h1>Programação</h1>, e assim por diante nas cinco páginas). O nome do evento continua acessível: ele está no alt do logo e no <title>.
Três pontos que valem nota:
O menu é uma lista (ul/li). Leitores de tela anunciam "lista com 5 itens" ao entrar nela — o usuário sabe o tamanho da navegação antes de percorrê-la. Uma sequência de <a> soltos não dá essa informação.
<nav aria-label="Principal"> distingue esta navegação de outras que a página pode ter (a do rodapé, uma trilha de "você está aqui", os filtros da programação). Sem o rótulo, o leitor de tela anuncia só "navegação", e o usuário não sabe qual.
aria-current="page" marca a página atual semanticamente, não só com cor. Quem não enxerga a cor (por daltonismo ou por usar leitor de tela) recebe a mesma informação. Em cada página do site, o atributo vai no link correspondente — e o CSS usa o atributo como seletor, então o destaque visual vem de graça.
O alt do logo diz para onde o link leva ("Página inicial") e o que a imagem é, porque um logo dentro de um link é, antes de tudo, um link. Na Aula 04 esse mesmo logo tinha alt="", porque o <h1> ao lado já dizia o nome do evento; agora que o logo virou link e o <h1> saiu do cabeçalho, o alt volta a carregar informação. O alt correto depende do contexto, não do arquivo.
Uma mudança de ordem, declarada. O menu passa de cinco itens em ordem de "índice" (Início, Programação, Inscrição, Palestrantes, Contato) para quatro itens de navegação mais um botão de ação no fim: "Inscreva-se". A decisão é de experiência de uso — a ação que o site quer que a pessoa faça deve estar no fim da linha de leitura e visualmente distinta do resto, não perdida no meio do menu. O rótulo muda de "Inscrição" (substantivo, nome de página) para "Inscreva-se" (verbo, chamada para ação) pelo mesmo motivo. O arquivo continua sendo inscricao.html.
.cabecalho{background:var(--cor-superficie);border-bottom:1pxsolidvar(--cor-borda);position:sticky;top:0;z-index:100;}.cabecalho__interno{display:flex;align-items:center;justify-content:space-between;gap:var(--espaco-grande);padding-block:var(--espaco-medio);}.logoimg{display:block;/* remove o espaço fantasma abaixo da imagem em linha */height:40px;width:auto;}.menu{display:flex;align-items:center;gap:1.5rem;list-style:none;}.menua{position:relative;/* referência para o sublinhado (::after) */display:block;padding:.5rem0;color:var(--cor-texto);text-decoration:none;font-weight:500;}/* Sublinhado que cresce — a Aula 09 explica transform e transition em detalhe */.menua::after{content:"";position:absolute;left:0;bottom:0;width:100%;height:2px;background:var(--cor-primaria);transform:scaleX(0);transition:transform200msease;}.menua:hover::after,.menua:focus-visible::after,.menua[aria-current="page"]::after{transform:scaleX(1);}.menua[aria-current="page"]{color:var(--cor-primaria);font-weight:600;}/* O botão-pílula de inscrição */.menua.menu__cta{padding:.5rem1.25rem;background:var(--cor-primaria);color:#fff;border-radius:999px;}.menua.menu__cta::after{display:none;/* o botão não recebe o sublinhado */}.menua.menu__cta:hover,.menua.menu__cta:focus-visible{background:var(--cor-secundaria);}
💡 Dica
Repare no seletor .menu a.menu__cta em vez de só .menu__cta. Como vimos na Aula 06, .menu a tem especificidade (0,1,1) e vence .menu__cta (0,1,0) — se você escrevesse só a classe, o color: #fff seria ignorado e o botão ficaria com texto escuro sobre fundo escuro. .menu a.menu__cta tem (0,2,1) e ganha. Quando um estilo "não pega", a especificidade é a primeira suspeita.
Duas decisões pequenas com efeito grande:
:focus-visible ao lado de :hover em todos os estados. Quem navega por teclado precisa ver onde está — e o contorno padrão do navegador, que você talvez tenha removido com outline: none em algum momento, era exatamente isso. Nunca remova o outline sem oferecer uma alternativa visível.
display: block nos links aumenta a área clicável para o padding inteiro, e não só para o texto. No celular, isso é a diferença entre acertar e errar o toque.
Quem navega por teclado não deveria ter que percorrer o menu inteiro, em toda página, para chegar ao conteúdo. O link de salto é o primeiro elemento do <body>: invisível para quem usa mouse, é o primeiro que aparece ao pressionar Tab.
site-evento/index.html — logo após <body> e o início do <main>
HTML
<body><ahref="#conteudo"class="salto">Pular para o conteúdo</a><headerclass="cabecalho"><divclass="container cabecalho__interno"><ahref="index.html"class="logo"><imgsrc="img/logo-sasi.svg"alt="Página inicial — Semana Acadêmica de Sistemas de Informação"></a><navaria-label="Principal"><ulclass="menu"><li><ahref="index.html"aria-current="page">Início</a></li><li><ahref="programacao.html">Programação</a></li><li><ahref="palestrantes.html">Palestrantes</a></li><li><ahref="contato.html">Contato</a></li><li><ahref="inscricao.html"class="menu__cta">Inscreva-se</a></li></ul></nav></div></header><mainid="conteudo"tabindex="-1"><h1>Semana Acadêmica de Sistemas de Informação</h1></main></body>
.salto{position:absolute;left:-9999px;/* fora da tela, mas presente para o teclado e o leitor de tela */top:1rem;padding:.75rem1.25rem;background:var(--cor-primaria);color:#fff;border-radius:var(--raio-borda);z-index:1000;}.salto:focus{left:1rem;/* ao receber foco, entra na tela */}
O tabindex="-1" no <main> permite que ele receba foco ao ser alvo do link (sem entrar na sequência normal do Tab), o que faz o leitor de tela começar a ler dali. Sem isso, alguns navegadores rolam até o conteúdo, mas o foco continua no link de salto.
🔎 Por baixo do capô
Por que left: -9999px e não display: none? Porque display: noneremove o elemento da árvore de acessibilidade: ele deixa de existir para o teclado e para o leitor de tela. Deslocar para fora da tela mantém o elemento "vivo" — invisível, mas focável. É o mesmo raciocínio que você vai reencontrar na Aula 09, quando display não puder ser animado.
Esse menu funciona perfeitamente em telas largas. No celular, cinco links não cabem lado a lado — e a solução é o menu "hambúrguer", que abre e fecha. A versão responsiva do menu fica para a Aula 08, porque depende de media queries e de um pouco de raciocínio mobile first que você ainda não viu. Hoje, o menu quebra linha de forma aceitável graças ao flex-wrap que você vai adicionar na Mão na massa.
💻 Mão na massa — Esqueleto do site do evento com Grid e Flexbox¶
Você vai aplicar tudo isso no site da Semana Acadêmica de Sistemas de Informação. Ao final, as cinco páginas terão o mesmo cabeçalho fixo com menu acessível, o rodapé no fim da tela, a página inicial com um herói em duas colunas, a programação com lateral de filtros e grade de cartões, e os palestrantes em uma galeria que se reorganiza sozinha.
Abra site-evento/css/estilo.css. Na seção 2 (variáveis), acrescente três variáveis ao bloco :root que você criou na Aula 06 e documente a escala de empilhamento em um comentário.
/* 2. Variáveis */:root{--cor-primaria:#0b3d5c;--cor-secundaria:#1a7fb5;--cor-texto:#333333;--cor-fundo:#f7f9fb;--cor-superficie:#ffffff;/* fundo de cabeçalho e cartões */--cor-borda:#dfe6ec;/* linhas divisórias */--fonte-base:"Inter",Arial,sans-serif;--espaco-pequeno:8px;--espaco-medio:16px;--espaco-grande:32px;--raio-borda:8px;--sombra-cartao:02px8pxrgba(0,0,0,0.1);--largura-max:1100px;/* largura máxima do conteúdo */}/* Escala de z-index do projeto: 100 cabeçalho fixo 900 sobreposições escuras (overlay) 1000 modais e link de salto */
Passo 2 — Rodapé no fim da tela e o contêiner central¶
Na seção 4 (layout), apague as três declarações do main que a Aula 06 escreveu (max-width, margin e padding) e ponha no lugar o padrão do body em coluna mais a classe .container reutilizável. A largura máxima continua sendo a mesma de sempre — 1100 px —, só que agora ela mora na variável --largura-max e é a .container que a aplica.
site-evento/css/estilo.css — seção 4 (layout), início
CSS
/* 4. Layout */body{display:flex;flex-direction:column;min-height:100vh;}main{flex:1;/* empurra o rodapé para o fim da janela */}.container{width:100%;max-width:var(--largura-max);margin-inline:auto;/* centraliza horizontalmente */padding-inline:var(--espaco-medio);}
margin-inline e padding-inline são as versões "lógicas" de margin-left/margin-right — funcionam também em idiomas escritos da direita para a esquerda. Use-as sempre que a intenção for "dos lados".
Onde a .container entra no HTML. Na Aula 05 ela era uma <div> dentro de cada região; na Aula 06 a <div> saiu de dentro do <main>. Hoje ela volta ao conteúdo principal, mas como classe do próprio elemento, sem <div> extra. Percorra as cinco páginas e garanta que cada uma tenha exatamente um contêiner no conteúdo:
Página
Onde vai a .container
index.html
na <section class="container hero"> (Passo 5)
programacao.html
no <main id="conteudo" tabindex="-1" class="container pagina"> (Passo 6)
palestrantes.html
no <main id="conteudo" tabindex="-1" class="container"> (Passo 7)
inscricao.html
no <main id="conteudo" tabindex="-1" class="container">
contato.html
no <main id="conteudo" tabindex="-1" class="container">
Sem esse passo, inscricao.html e contato.html ficam com o conteúdo colado nas bordas da janela em monitores largos — e é o erro mais comum desta aula.
Coloque o cabeçalho da seção 5.1 nas cinco páginas, trocando o aria-current="page" para o link da página correspondente. Em programacao.html, por exemplo:
site-evento/programacao.html — cabeçalho
HTML
<ahref="#conteudo"class="salto">Pular para o conteúdo</a><headerclass="cabecalho"><divclass="container cabecalho__interno"><ahref="index.html"class="logo"><imgsrc="img/logo-sasi.svg"alt="Página inicial — Semana Acadêmica de Sistemas de Informação"></a><navaria-label="Principal"><ulclass="menu"><li><ahref="index.html">Início</a></li><li><ahref="programacao.html"aria-current="page">Programação</a></li><li><ahref="palestrantes.html">Palestrantes</a></li><li><ahref="contato.html">Contato</a></li><li><ahref="inscricao.html"class="menu__cta">Inscreva-se</a></li></ul></nav></div></header>
Antes de colar o CSS novo, apague da seção 4 da folha de estilo as três regras de cabeçalho que a Aula 06 escreveu: header { … }, header nav ul { … } e header nav li { display: inline-block; margin-right: var(--espaco-medio) }. As regras header h1, header h2 e header a também saem — o cabeçalho agora tem fundo claro, e texto branco nele ficaria invisível. Se você deixar o margin-right do header nav li no arquivo, ele soma com o gap: 1.5rem do .menu e o espaçamento entre os itens fica dobrado; é exatamente o primeiro sintoma da tabela de Erros comuns desta aula.
Feito isso, cole o CSS do cabeçalho e do menu da seção 5.2 na seção 4 da folha de estilo, e acrescente flex-wrap: wrap ao .menu, para que os links quebrem linha em vez de estourar o cabeçalho quando a janela for estreita — um paliativo até a Aula 08:
Adicione o <a href="#conteudo" class="salto"> como primeiro filho do <body> em todas as páginas, coloque id="conteudo" tabindex="-1" no <main> de cada uma e cole o CSS de .salto na seção 6 (utilitários).
A página inicial abre com um "herói": título, texto de chamada, dois botões e a imagem do evento. Em telas largas, texto e imagem ficam lado a lado; em telas estreitas, empilham — e o auto-fit decide sozinho.
⚠️ Atenção
Este bloco substitui a <section class="hero"> que a Aula 05 criou (aquela com o <h2>, um parágrafo e um botão só) e também o <picture> do banner da Aula 04, cuja imagem passa a ser a do herói. Apague os dois e cole o <main> abaixo no lugar. As seções "Sobre o evento", "Como participar", "Glossário", "Destaques desta edição" e "O evento em números" continuam onde estão, logo depois do herói, dentro do <main>.
site-evento/index.html — conteúdo do <main>
HTML
<mainid="conteudo"tabindex="-1"><sectionclass="container hero"><divclass="hero__texto"><h1>Semana Acadêmica de Sistemas de Informação</h1><p>Três dias de palestras, minicursos e maratona de programação no campus de Sinop. Aberto a estudantes de todos os cursos.</p><divclass="hero__acoes"><aclass="botao"href="inscricao.html">Inscreva-se</a><aclass="botao botao--contorno"href="programacao.html">Ver programação</a></div></div><imgsrc="img/banner.jpg"alt="Auditório lotado durante a abertura da edição anterior"width="1200"height="800"></section></main>
O segundo botão usa .botao--contorno, o modificador que você já escreveu na Aula 06 — fundo transparente, texto na cor primária e inversão no :hover/:focus-visible. Não crie um .botao--secundario: seria o mesmo componente com outro nome, e componentes duplicados é como uma folha de estilo começa a apodrecer. Se você não encontrar o .botao--contorno na seção 5 da sua folha, é sinal de que o Passo 6 da Aula 06 ficou pela metade — volte lá antes de seguir.
Passo 6 — Programação: lateral de filtros e grade de cartões¶
A programação é a página mais rica do site. Em telas largas, ela tem uma lateral com filtros por dia e uma área de conteúdo com os cartões de cada atividade. É Grid para a estrutura (lateral + conteúdo) e Grid de novo, com auto-fit, para os cartões — e Flexbox dentro de cada cartão.
⚠️ Atenção
Este <main>substitui o conteúdo da programacao.html das Aulas 02 e 04: a <table> dos três dias, a seção "Trilhas do evento" e a seção "As cinco atividades mais procuradas" saem daqui e dão lugar aos cartões. As seções de vídeo, áudio e mapa (Passos 5 a 7 da Aula 04) continuam, depois dos cartões, dentro da <section class="conteudo">. E as regras de table, caption, th, td, thead, tbody e tfoot que você escreveu na Aula 06 ficam na folha de estilo: elas continuam servindo a tabela de horário de atendimento de contato.html.
Repare também em onde o <h1> está: fora da <section class="conteudo">, como primeiro filho do <main>. Se ele ficasse depois do <aside>, a página abriria com um <h2> ("Filtrar por dia") antes do <h1> — hierarquia quebrada, e uma reprovação certa na auditoria de acessibilidade do Lighthouse.
site-evento/programacao.html — conteúdo do <main>
HTML
<mainid="conteudo"tabindex="-1"class="container pagina"><h1>Programação</h1><asideclass="lateral"><h2>Filtrar por dia</h2><navaria-label="Dias do evento"><ulclass="lista-filtros"><li><ahref="#dia-1">Dia 1</a></li><li><ahref="#dia-2">Dia 2</a></li><li><ahref="#dia-3">Dia 3</a></li></ul></nav></aside><sectionclass="conteudo"><h2id="dia-1">Dia 1</h2><ulclass="cartoes"><liclass="cartao"><h3>Abertura e palestra magna</h3><pclass="cartao__meta"><timedatetime="19:00">19h</time> · Auditório Central</p><p>O futuro do desenvolvimento web e o papel de quem está começando agora.</p><aclass="botao"href="inscricao.html">Inscrever-se</a></li><liclass="cartao"><spanclass="cartao__selo">Esgotado</span><h3>Minicurso: Git e GitHub do zero</h3><pclass="cartao__meta"><timedatetime="20:00">20h</time> · Laboratório 2</p><p>Versionamento, branches e o primeiro pull request. Traga o notebook.</p><aclass="botao"href="inscricao.html"aria-disabled="true">Lista de espera</a></li><liclass="cartao"><h3>Mesa-redonda: mercado de trabalho em Sinop</h3><pclass="cartao__meta"><timedatetime="20:00">20h</time> · Sala 105</p><p>Egressos e empresas da região conversam sobre estágios e primeiro emprego.</p><aclass="botao"href="inscricao.html">Inscrever-se</a></li></ul><h2id="dia-2">Dia 2</h2><ulclass="cartoes"><liclass="cartao"><h3>Minicurso: acessibilidade na prática</h3><pclass="cartao__meta"><timedatetime="19:00">19h</time> · Laboratório 1</p><p>Teste seu site com leitor de tela e só com o teclado.</p><aclass="botao"href="inscricao.html">Inscrever-se</a></li><liclass="cartao"><h3>Palestra: segurança em aplicações web</h3><pclass="cartao__meta"><timedatetime="20:30">20h30</time> · Auditório Central</p><p>Os dez erros mais comuns e como evitá-los desde o primeiro commit.</p><aclass="botao"href="inscricao.html">Inscrever-se</a></li></ul><h2id="dia-3">Dia 3</h2><ulclass="cartoes"><liclass="cartao"><h3>Maratona de programação</h3><pclass="cartao__meta"><timedatetime="18:30">18h30</time> · Laboratórios 1 e 2</p><p>Equipes de três pessoas, quatro horas, dez problemas. Premiação no encerramento.</p><aclass="botao"href="inscricao.html">Inscrever equipe</a></li><liclass="cartao"><h3>Encerramento e premiação</h3><pclass="cartao__meta"><timedatetime="22:00">22h</time> · Auditório Central</p><p>Resultados da maratona, sorteios e confraternização.</p><aclass="botao"href="inscricao.html">Inscrever-se</a></li></ul></section></main>
site-evento/css/estilo.css — seção 4 (layout) e seção 5 (componentes)
CSS
/* Estrutura da página de programação: lateral + conteúdo */.pagina{display:grid;grid-template-columns:240px1fr;grid-template-areas:"titulo titulo""lateral conteudo";gap:var(--espaco-grande);padding-block:var(--espaco-grande);}.pagina>h1{grid-area:titulo;}.lateral{grid-area:lateral;}.conteudo{grid-area:conteudo;}.lateral{align-self:start;/* não estica até o fim da coluna */position:sticky;/* acompanha a rolagem, abaixo do cabeçalho */top:88px;/* altura do cabeçalho + respiro */}.lista-filtros{list-style:none;display:flex;flex-direction:column;gap:var(--espaco-pequeno);}.lista-filtrosa{display:block;padding:var(--espaco-pequeno)var(--espaco-medio);border-left:3pxsolidvar(--cor-borda);color:var(--cor-texto);text-decoration:none;}.lista-filtrosa:hover,.lista-filtrosa:focus-visible{border-left-color:var(--cor-primaria);color:var(--cor-primaria);}/* Grade de cartões: quantas colunas couberem, mínimo 280px cada */.cartoes{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:var(--espaco-medio);margin-block:var(--espaco-medio)var(--espaco-grande);}/* 5. Componentes */.cartao{position:relative;/* referência para o selo */display:flex;/* Flexbox DENTRO do cartão */flex-direction:column;gap:var(--espaco-pequeno);padding:var(--espaco-medio);background:var(--cor-superficie);border:1pxsolidvar(--cor-borda);border-radius:var(--raio-borda);box-shadow:var(--sombra-cartao);}.cartao.botao{margin-top:auto;/* empurra o botão para o fim, alinhando todos os cartões */align-self:flex-start;/* o botão não estica até a largura do cartão */}.cartao__meta{color:var(--cor-secundaria);font-size:.875rem;font-weight:600;}.cartao__selo{position:absolute;top:var(--espaco-pequeno);right:var(--espaco-pequeno);padding:2px10px;font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;background:#b42318;color:#fff;border-radius:999px;}
Repare no truque margin-top: auto dentro de um contêiner flex em coluna: a margem automática absorve todo o espaço sobrando e empurra o botão para o rodapé do cartão. Como align-items: stretch (o padrão do Grid) deixa todos os cartões da linha com a mesma altura, os botões ficam alinhados mesmo que os textos tenham tamanhos diferentes.
Passo 7 — Palestrantes: galeria que se reorganiza sozinha¶
A página de palestrantes reaproveita .cartoes e .cartao, com uma variação para a foto.
⚠️ Atenção
Este <main>substitui os seis <article> que as Aulas 02 e 04 escreveram (nome em <h3>, dois parágrafos e um <dl> de atividades e contato). Os nomes e as fotos são exatamente os mesmos — muda a marcação, que passa a ser uma <ul class="cartoes"> com um <li class="cartao"> por pessoa. Mostramos quatro aqui para o exemplo caber; repita o padrão para os seis do elenco.
site-evento/palestrantes.html — conteúdo do <main>
HTML
<mainid="conteudo"tabindex="-1"class="container"><h1>Palestrantes</h1><p>Profissionais e pesquisadores que vão compartilhar experiências nesta edição.</p><ulclass="cartoes"><liclass="cartao cartao--palestrante"><imgclass="cartao__foto"src="img/palestrante-01.jpg"alt="Ana Lúcia Ferreira"width="400"height="400"><h2>Ana Lúcia Ferreira</h2><pclass="cartao__meta">Professora e pesquisadora · Inteligência Artificial</p><p>Pesquisa redes neurais para prever a safra de soja e ministra o minicurso de redes neurais.</p></li><liclass="cartao cartao--palestrante"><imgclass="cartao__foto"src="img/palestrante-02.jpg"alt="Bruno Takahashi"width="400"height="400"><h2>Bruno Takahashi</h2><pclass="cartao__meta">Startup AgroData · Ciência de Dados</p><p>Constrói dashboards que os produtores realmente usam e fala sobre dados abertos.</p></li><liclass="cartao cartao--palestrante"><imgclass="cartao__foto"src="img/palestrante-03.jpg"alt="Carla Mendes"width="400"height="400"><h2>Carla Mendes</h2><pclass="cartao__meta">UFMT · Segurança</p><p>Pesquisa o que um ataque de phishing ensina sobre experiência de uso.</p></li><liclass="cartao cartao--palestrante"><imgclass="cartao__foto"src="img/palestrante-04.jpg"alt="Diego Nascimento"width="400"height="400"><h2>Diego Nascimento</h2><pclass="cartao__meta">Prefeitura de Sinop · Desenvolvimento Web</p><p>Trabalha com acessibilidade em portais públicos e conta os erros que a equipe já viu.</p></li></ul></main>
.cartao--palestrante{align-items:center;/* centraliza foto, nome e texto no eixo transversal */text-align:center;}.cartao__foto{width:120px;height:120px;border-radius:50%;/* foto redonda */object-fit:cover;/* recorta sem distorcer — a Aula 08 aprofunda */}
⚠️ Atenção
Este rodapé substitui o <footer> de três parágrafos da Aula 02 (realização, e-mail/telefone e linha de copyright). Nenhuma informação se perde: a realização vira a coluna "Sobre o evento", o e-mail vai para o <address> da coluna "Contato" e a linha de copyright vira o .rodape__creditos. Apague o bloco antigo nas cinco páginas e cole este no lugar — inclusive o <nav aria-label="Rodapé"> que a Aula 05 acrescentou em index.html, cujos links agora vivem na coluna "Links".
site-evento/index.html — antes de </body>, em todas as páginas
HTML
<footerclass="rodape"><divclass="container rodape__grade"><section><h2>Sobre o evento</h2><p>Organizado por professores e estudantes dos cursos de computação, com apoio do centro acadêmico.</p></section><section><h2>Links</h2><ul><li><ahref="programacao.html">Programação completa</a></li><li><ahref="inscricao.html">Inscrições</a></li><li><ahref="contato.html">Fale com a organização</a></li></ul></section><section><h2>Contato</h2><address><ahref="mailto:semana@exemplo.edu.br">semana@exemplo.edu.br</a><br>
Avenida dos Ingás, 3001 — Sinop, MT
</address></section></div><pclass="rodape__creditos">Semana Acadêmica de Sistemas de Informação</p></footer>
A grade de cartões e o rodapé já se adaptam sozinhos graças ao auto-fit. A página de programação, não: com 240px 1fr, em um celular a coluna de conteúdo fica com 100 px de largura. Por hoje, uma media query simples resolve — a Aula 08 vai inverter essa lógica para mobile first e formalizar os breakpoints.
/* 7. Media queries */@media(max-width:1023px){.pagina{grid-template-columns:1fr;grid-template-areas:"titulo""conteudo""lateral";/* no celular, os filtros vão para depois do conteúdo */}.lateral{position:static;/* deixa de acompanhar a rolagem */}}
Abra index.html com o Live Server. O cabeçalho deve ficar grudado no topo ao rolar, com o logo à esquerda e o menu à direita, e o link "Início" destacado com o sublinhado na cor primária.
Pressione Tab uma vez: o botão "Pular para o conteúdo" deve aparecer no canto superior esquerdo. Pressione Enter: o foco vai para o <main>. Continue com Tab: cada link do menu mostra o sublinhado crescendo.
Abra contato.html (a página com menos conteúdo): o rodapé deve estar colado no fim da janela, não flutuando no meio, e o conteúdo deve parar em 1100 px no centro — se ele encostar nas bordas, faltou a .container no <main> desta página. Confira o mesmo em inscricao.html.
Passe o mouse entre dois itens do menu e meça o espaço no DevTools: ele deve ser um único gap de 24 px. Se parecer o dobro, a regra header nav li da Aula 06 continua na folha — apague-a.
Em programacao.html, a lateral fica à esquerda e os cartões à direita, em colunas de no mínimo 280 px; o selo "Esgotado" aparece no canto superior direito do minicurso de Git; todos os botões de uma mesma linha ficam alinhados na base. Redimensione a janela: abaixo de 1024 px, tudo vira uma coluna e a lateral vai para o fim.
Em palestrantes.html, as fotos são redondas e os cartões se reorganizam de 4 para 3, 2 e 1 coluna conforme você estreita a janela — sem nenhuma media query.
No DevTools, clique no selo grid ao lado de <ul class="cartoes"> e no selo flex ao lado de <div class="cabecalho__interno"> e confira, com o overlay, que a estrutura é a que você desenhou.
A1. Explique a diferença entre position: relative, absolute e fixed quanto a dois critérios: a referência de posicionamento e a ocupação de espaço no fluxo.
A2. Por que um elemento com position: absolute costuma exigir position: relative no elemento pai? O que acontece se o pai não tiver essa declaração?
A3. Em um contêiner com display: flex e flex-direction: row, qual propriedade alinha os itens horizontalmente? E verticalmente? E se a direção for column?
A4. Diferencie space-between, space-around e space-evenly. Desenhe (em papel ou em texto) três itens em cada caso, marcando os espaços.
A5. O que significa flex: 1? Escreva sua forma expandida (as três propriedades) e explique o que cada valor faz.
A6. Escreva o CSS para centralizar perfeitamente um elemento na tela, horizontal e verticalmente, usando Flexbox. Depois reescreva usando Grid com uma linha só.
A7. O que a unidade fr representa? Em grid-template-columns: 200px 1fr 2fr, com um contêiner de 1100 px e gap: 0, qual é a largura de cada coluna? Mostre a conta.
A8. Explique, palavra por palavra, o que faz repeat(auto-fit, minmax(250px, 1fr)). Quantas colunas ela cria em uma janela de 1100 px? E em uma de 600 px?
A9. Escreva um grid-template-areas para um layout com cabeçalho no topo (largura total), lateral à esquerda, conteúdo à direita e rodapé embaixo (largura total). Inclua o grid-template-columns e o grid-template-rows correspondentes.
A10. Quando você usaria Flexbox e quando usaria Grid? Dê dois exemplos concretos de cada, tirados do site do evento.
A11. Por que float não deve mais ser usado para layout? Cite o único caso em que ele ainda é a ferramenta certa.
B1. Construa uma barra de navegação com Flexbox: logo à esquerda, cinco links à direita, item ativo destacado com aria-current="page". Em telas abaixo de 768 px, os links devem virar uma coluna centralizada abaixo do logo.
Resultado esperado: em 1200 px, logo e links na mesma linha, com space-between; em 500 px, o logo centralizado em cima e os cinco links empilhados e centralizados abaixo; o link ativo tem cor e sublinhado diferentes; Tab percorre os links na ordem do HTML com foco visível.
Dica
Na media query, troque flex-direction do contêiner do cabeçalho para column e do .menu também; align-items: center centraliza os dois. Não use order — a ordem do HTML já é a que você quer.
B2. Implemente o layout "santo graal": cabeçalho, três colunas (lateral esquerda fixa de 200 px, conteúdo elástico, lateral direita fixa de 200 px) e rodapé, com o rodapé sempre no fim da janela mesmo com pouco conteúdo. Em telas pequenas, tudo vira uma única coluna. Faça com Grid e áreas nomeadas.
Resultado esperado: em 1200 px, cinco áreas visíveis com grid-template-areas de três linhas; com um parágrafo só no conteúdo, o rodapé continua colado no fim da janela; abaixo de 768 px, as áreas se empilham na ordem cabeçalho → conteúdo → lateral esquerda → lateral direita → rodapé.
Dica
Use min-height: 100vh e grid-template-rows: auto 1fr auto no contêiner: a linha 1fr absorve o espaço sobrando. Na media query, redesenhe as áreas com uma palavra por linha — a ordem das strings define a ordem visual, sem tocar no HTML.
B3. Crie uma seção de "planos de inscrição" para o site do evento com três planos lado a lado (Flexbox): Estudante, Profissional e Apoiador. O do meio deve ser destacado (maior, com borda colorida e um selo "Mais popular" posicionado com absolute). Responsivo: os três empilham abaixo de 768 px.
Resultado esperado: três cartões com a mesma altura em telas largas, o do meio 8% maior (transform: scale(1.08) ou padding maior) e com borda na cor primária; o selo fica preso no canto superior direito do cartão do meio, mesmo ao redimensionar; no celular, os cartões ficam um abaixo do outro e o do meio deixa de ser maior.
Dica
align-items: stretch (o padrão) já iguala as alturas. Para o selo, position: relative no cartão e absolute no selo — a receita da seção 1.2. Lembre-se de flex: 1 1 260px nos cartões para que eles cresçam e quebrem linha.
B4. Reescreva o layout do exercício B3 duas vezes: uma versão só com Flexbox e outra só com Grid. Escreva meia página comparando a quantidade de código, a legibilidade e a facilidade de alteração de cada abordagem (ex.: o que muda para acrescentar um quarto plano?).
Resultado esperado: dois arquivos HTML funcionais e visualmente idênticos, e um texto de comparação com pelo menos três diferenças concretas, apontando qual versão você escolheria para o site do evento e por quê.
Dica
Conte as linhas de CSS de cada versão. Na versão Grid, experimente grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)) e veja o que acontece ao adicionar um quarto cartão. Na versão Flexbox, veja o que flex-wrap faz com um número ímpar de cartões na última linha.
B5. Construa um painel (dashboard) da organização do evento com Grid: cabeçalho, quatro cartões de indicadores na primeira linha (inscritos, vagas, palestrantes, minicursos), um cartão grande de "inscrições por dia" ocupando três colunas e um de "últimas inscrições" ocupando uma coluna na segunda linha, e uma tabela de atividades ocupando toda a largura na terceira. Responsivo em três breakpoints.
Resultado esperado: em 1200 px, uma grade de quatro colunas com os spans corretos; em 768 px, duas colunas (os indicadores em 2 × 2, o gráfico em largura total); no celular, tudo em uma coluna; a tabela nunca estoura a largura (use um contêiner com overflow-x: auto).
Dica
Defina grid-template-columns: repeat(4, 1fr) na base e use grid-column: span 3 e span 4 nos itens grandes. Nas media queries, troque o repeat(4, 1fr) por repeat(2, 1fr) e 1fr, e ajuste os spans para que nenhum item peça mais colunas do que a grade tem — se pedir, o Grid cria colunas implícitas e o layout estoura.
C1. Base do projeto autoral. Defina o tema do seu projeto (o "site do evento" da sua versão: uma feira, um campeonato, uma semana cultural, um curso de extensão) e construa o esqueleto completo de todas as páginas: HTML semântico, estrutura de layout com Grid e áreas nomeadas, componentes internos com Flexbox, sistema de design em variáveis, navegação funcional entre as páginas, cabeçalho fixo e rodapé consistentes em todas elas, link de salto funcionando. Produza também um wireframe (papel fotografado, Figma ou Excalidraw) de três larguras: celular, tablet e desktop. Este exercício é a primeira etapa do que o Marco 2 vai cobrar (Aula 10).
Dica
Comece pelo wireframe, não pelo código: desenhe as três larguras em dez minutos e só então decida quais áreas nomeadas cada página precisa. Reaproveite .container, .cabecalho, .menu, .cartoes e .rodape da Mão na massa — o que muda no seu projeto é o conteúdo e as cores, não a arquitetura. Valide o HTML de cada página no W3C antes de estilizar.
Você consegue levar 24 sapos para as vitórias-régias certas usando só justify-content, align-items e flex-wrap? E regar 28 cenouras com grid-column, grid-area e grid-template-areas? Os dois jogos foram criados para fixar, por repetição, exatamente as propriedades desta aula — e muita gente que "já sabia Flexbox" descobre no nível 18 que não sabia align-content. Jogue os dois em português (https://flexboxfroggy.com/#pt-br e https://cssgridgarden.com/#pt-br) e anote o que travou.
Critérios de pronto
Captura de tela do último nível de cada jogo concluído (nível 24 do Froggy e nível 28 do Garden).
Um arquivo aprendizados.md com três propriedades ou valores que você não conhecia (ou usava errado) antes dos jogos, com uma frase explicando cada um.
Para cada uma das três, um trecho do site do evento onde ela poderia ser aplicada.
Pistas
Se travar em um nível, abra a referência de Flexbox da MDN em pt-BR e procure a propriedade que o enunciado do nível cita — o jogo sempre diz qual é.
No Froggy, os níveis a partir do 19 combinam flex-direction com justify-content: lembre que o eixo principal muda de lugar.
No Garden, grid-column: 2 / span 3 e grid-column: 2 / 5 fazem a mesma coisa — os níveis finais testam se você entende as duas formas.
O código abaixo era para produzir um cabeçalho fixo com menu à direita, uma página com lateral à esquerda e conteúdo à direita, e um selo "Esgotado" no canto do cartão. Nada disso acontece: o cabeçalho rola junto com a página, a lateral cai embaixo do conteúdo, o selo aparece no canto da janela e o menu tem marcadores e espaços duplos. Há cinco bugs. Encontre e corrija todos usando apenas o DevTools como ferramenta de investigação — sem reescrever do zero.
caca-ao-bug.html
HTML
<body><headerclass="topo"><divclass="topo__interno"><aclass="logo"href="index.html">Semana</a><navaria-label="Principal"><ulclass="menu"><li><ahref="index.html">Início</a></li><li><ahref="programacao.html">Programação</a></li><li><ahref="contato.html">Contato</a></li></ul></nav></div></header><mainclass="grade"><asideclass="lateral">Filtros</aside><sectionclass="conteudo"><divclass="cartao"><spanclass="selo">Esgotado</span><h2>Minicurso de Git</h2><p>Versionamento do zero ao primeiro pull request.</p></div></section></main></body>
A lateral fica à esquerda e o conteúdo à direita, na mesma linha.
O selo "Esgotado" fica no canto superior direito do cartão, mesmo ao rolar e redimensionar.
O menu não tem marcadores de lista e os links têm exatamente 24 px de espaço entre si.
Um comentário acima de cada correção explica o bug em uma linha (por que o comportamento errado acontecia).
Pistas
sticky precisa de duas coisas para funcionar: uma delas está faltando na regra, a outra está sendo sabotada por um ancestral — releia a seção 1.2 e o Investigue da seção 1.5.
No DevTools, ative o overlay da grade e "Show area names": o nome que aparece na primeira coluna é o mesmo que a .lateral está pedindo?
absolute procura o ancestral posicionado mais próximo. Qual é o ancestral posicionado mais próximo do selo neste código?
gap e margin não se anulam — se somam. E ul tem um estilo padrão que ninguém removeu.
A página inicial do site do evento precisa de um bloco de destaques em formato de revista: sete cartões de tamanhos diferentes — um grande (2 × 2), dois largos (2 × 1), um alto (1 × 2) e três pequenos (1 × 1) — encaixados sem buracos, como um mosaico. O detalhe: quando a janela estreita e a grade perde colunas, os buracos aparecem, a menos que você conheça uma propriedade que faz o Grid "preencher para trás". Descubra qual é e construa o mosaico.
Critérios de pronto
Em 1100 px, os sete cartões ocupam uma grade de quatro colunas sem nenhuma célula vazia.
Em 700 px (duas colunas) e em 400 px (uma coluna), continua não havendo buracos e nenhum cartão pede mais colunas do que existem.
Nenhum cartão é posicionado com números de linha fixos (grid-column: 3 / 5) — só com span.
A ordem de leitura por teclado (Tab nos links dos cartões) faz sentido mesmo quando o Grid reordena visualmente.
Pistas
Procure grid-auto-flow na MDN e leia sobre o valor dense.
grid-auto-rows com um valor fixo (ou minmax) dá altura às linhas implícitas, para que span 2 em linhas tenha efeito visível.
Na media query de duas colunas, reduza todo span maior que 2 para span 2; em uma coluna, span 1 para todos.
dense pode mover um cartão para antes de outro que vem primeiro no HTML. Teste com Tab e, se a ordem ficar estranha, reordene o HTML — não o CSS.
Você consegue reproduzir a página inicial de um site que usa todo dia? Escolha a home de um site conhecido (o portal da sua universidade ou escola, um jornal, uma loja, a página inicial do GitHub) e reproduza seu layout — estrutura e disposição, com conteúdo próprio e sem copiar imagens — usando Grid para a página e Flexbox para os componentes, com responsividade em três larguras. Requisito inegociável: zero float e zero position: absolute para layout (o absolute só pode aparecer em selos e ícones). Ao terminar, você vai perceber quanto dos sites que admira é só Grid e Flexbox bem combinados. Isso entra bem no Marco 2 da unidade.
Critérios de pronto
Três pares de capturas lado a lado (original × sua versão) em 375 px, 768 px e 1440 px.
O arquivo CSS tem, no topo, um comentário com o desenho das áreas nomeadas de cada largura.
O DevTools não mostra nenhum float e nenhum position: absolute em elementos estruturais (cabeçalho, colunas, seções, rodapé).
O menu principal é uma lista dentro de <nav aria-label>, com aria-current e link de salto.
HTML validado sem erros no W3C.
Pistas
Antes de escrever CSS, abra o site escolhido com o DevTools e clique nos selos grid e flex: muitos sites profissionais deixam a estrutura à mostra.
Desenhe o grid-template-areas das três larguras em papel primeiro; se você não consegue desenhar, não consegue codificar.
Comece pela largura maior (a mais complexa) e reduza — nesta aula ainda é aceitável; na Aula 08 você vai inverter.
Onde o original usa uma imagem de fundo com texto por cima, use uma célula do Grid com background-image e um div com Flexbox para o texto — sem absolute.
Parte 1 — Leitura (20 min). SILVA, Maurício Samy. Criando sites com HTML, capítulos de posicionamento e layout. MDN Web Docs em pt-BR: os guias "Conceitos básicos do Flexbox" e "Conceitos básicos do Grid Layout" (links em "Para aprofundar"). Anote uma propriedade de cada guia que não apareceu nesta aula.
Parte 2 — Produção (30 min). No seu projeto autoral:
Exercícios B1 (barra de navegação) e B5 (dashboard), em arquivos separados na pasta exercicios/aula07/.
O layout principal do projeto construído com Grid e áreas nomeadas em pelo menos uma página (a mais complexa), com Flexbox no interior dos componentes.
O menu de navegação completo em todas as páginas: lista semântica, nav aria-label, aria-current na página atual, :focus-visible em todos os links e link de salto funcionando.
Parte 3 — Discussão (10 min). Em texto próprio — ou no fórum da turma, se você está cursando esta trilha em grupo —: traga um componente do seu projeto (um trecho de HTML + CSS), diga qual dos dois você usou (Grid ou Flexbox) e justifique tecnicamente com base na tabela da seção 4. Se puder, compare a escolha com a de outra pessoa.
Critério de pronto: ao pressionar Tab na primeira página do seu projeto, o link de salto aparece; ao pressionar Enter, o foco vai para o conteúdo; navegando pelo menu, cada link mostra foco visível e a página atual está marcada com aria-current; ao abrir a página mais curta, o rodapé está no fim da janela; ao clicar nos selos grid/flex do DevTools, a estrutura desenhada é a que você planejou.
Guarde no seu repositório: commit + push (ou a pasta do projeto, se ainda não usa Git).
web.dev — Learn CSS: https://web.dev/learn/css — os módulos "Flexbox", "Grid" e "Z-index and stacking contexts" explicam o contexto de empilhamento com ilustrações.
SILVA, Maurício Samy. Criando sites com HTML: sites de alta qualidade com HTML e CSS. Novatec, 2008 — capítulos de posicionamento e layout (contexto histórico do float; compare com o que você aprendeu hoje).
TERUEL, Evandro C. HTML 5 — Guia Prático. Saraiva, 2014 — capítulo sobre estruturação de páginas com os elementos semânticos que o Grid organiza.
Na próxima aula, o site do evento vai para o celular de verdade: você vai reescrever a folha de estilo no modo mobile first, definir breakpoints onde o layout quebra (e não onde o iPhone manda), transformar o menu em um hambúrguer acessível e respeitar as preferências do usuário — tema escuro e redução de movimento.