Capítulo 37
Primeiro a tela pequena
6 min de leitura 1.048 palavras 2 gravuras
Esta é o capítulo 37 de 52 do volume Aprenda a Web. O projeto-fio é a Oficina Costeira, um coletivo fictício de design em João Pessoa. O exemplo está em exemplos/37-tela-pequena/. Em cada capítulo: leia, copie, mude uma coisa, preveja, recarregue e confira.
O que você vai aprender
- Começar o CSS pela coluna estreita (mobile first).
- Declarar o viewport correto.
- Empilhar cabeçalho, conteúdo e rodapé sem horizontal.
- Usar
min()e largura fluida em vez dewidth: 980px. - Preparar o terreno para o capítulo de media queries.
- Testar zoom, teclado e largura de 320 px.
Por que o telefone primeiro
A maioria das visitas chega numa coluna estreita. Se você desenha o desktop e depois “espreme”, o CSS vira uma lista de exceções. Se você desenha a coluna única e depois amplia, cada media query só acrescenta.
Mobile first neste volume significa: as regras fora de @media servem à tela pequena. @media (min-width: …) entra no capítulo 38 para o extra.
A origem antiga deste tópico usava float no layout inteiro. Aqui a coluna usa fluxo, Flexbox no cabeçalho e Grid quando a página ganhar trilhos. Float fica para imagem com texto ao lado, como nos capítulos anteriores.
Viewport
Sem o meta viewport, o telefone finge uma tela de 980 px e reduz tudo. O texto vira miniatura.
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Início — Oficina Costeira</title>
<link rel="stylesheet" href="assets/stylesheets/main.css">
</head>
<body>
<a class="skip" href="#conteudo">Pular para o conteúdo</a>
<header class="site-header">
<a class="brand" href="index.html">Oficina Costeira</a>
<nav aria-label="Principal">
<ul class="menu">
<li><a href="index.html" aria-current="page">Início</a></li>
<li><a href="projetos.html">Projetos</a></li>
<li><a href="equipe.html">Equipe</a></li>
</ul>
</nav>
</header>
<main id="conteudo">
<h1>Oficina Costeira</h1>
<p>Coletivo fictício de design em João Pessoa. Este site começa na coluna do telefone.</p>
</main>
<footer>
<p>Conteúdo fictício para estudo. Nada é enviado a um servidor.</p>
</footer>
</body>
</html>
width=device-width casa a largura CSS com a tela. initial-scale=1 evita zoom inicial. Não trave user-scalable=no: quem precisa ampliar some o controle.
Copie. Apague o meta viewport. Preveja a página “de cartaz” no emulador de telefone. Recarregue. Devolva o meta.
Erro comum: width=1024 no viewport “para parecer desktop”. O telefone volta a pinçar. Deixe device-width.
Caixa que cabe
*,
*::before,
*::after {
box-sizing: border-box;
}
.wrap {
width: min(70rem, calc(100% - 2rem));
margin-inline: auto;
}
img,
video,
svg {
max-width: 100%;
height: auto;
display: block;
}
border-box inclui padding na largura. min(70rem, calc(100% - 2rem)) é coluna fluida: nunca estoura a janela, nunca perde a margem de 1 rem de cada lado. Nada de width: 960px no body.
text-size-adjust: 100% evita o telefone inflar o tipo sem o seu pedido. Use com parcimônia; o zoom do usuário continua livre.
Uma coluna, menu que quebra
.menu {
list-style: none;
display: flex;
flex-wrap: wrap;
gap: 0.75rem 1.25rem;
}
.faixa {
display: flex;
flex-wrap: wrap;
gap: 1rem;
align-items: center;
justify-content: space-between;
}
Na tela estreita a marca fica numa linha e o menu na seguinte. Os destinos permanecem visíveis. Não esconda o nav. Cartões empilham: display: grid; gap: 1rem; grid-template-columns: 1fr.
O cabeçalho pode ser flex-wrap. O main é um bloco. O rodapé é um bloco. Três faixas, uma coluna. Isso já é um site. O capítulo 38 só acrescenta trilhos quando a janela pedir.
Parágrafo com max-width: 65ch evita linha de 40 palavras no desktop. No telefone, 65ch é maior que a tela, então a linha acompanha a coluna. Não precisa de media query para isso.
Linha de texto: max-width: 65ch no parágrafo. Na coluna estreita a medida acompanha a tela. No desktop a linha não vira uma faixa interminável.

O que ainda não fazer
Não escreva ainda @media (max-width: 600px) para “consertar o desktop”. Esse é o caminho invertido. A base já é o telefone.
Não use tabelas de layout. Não force position: fixed no cabeçalho: no telefone a barra do navegador briga com o menu grudado.
Metas antigas handheldfriendly e mobileoptimized não são necessárias nos navegadores deste volume. O viewport atual basta.
Conferir na palma
Estreite a janela até cerca de 320 px. Não deve aparecer barra horizontal. Tab: skip-link, marca, menu, conteúdo. Zoom 200%: o texto reflow, não corta.
No emulador do navegador, escolha um aparelho. Isso é palpite de largura, não o aparelho real. Por isso o capítulo 39 testa em mais de um motor.
Sirva em 127.0.0.1. O telefone da mesma rede não é obrigatório; a janela estreita no computador já revela o overflow.
Toque em cada link com o dedo imaginário de 48 px: o alvo do menu não pode ser uma linha de 12 px. padding nos a ajuda. gap no flex separa os alvos.
lang="pt-BR" continua obrigatório. O telefone hifeniza e o leitor de tela escolhem voz com base nisso. Viewport sem idioma ainda é documento incompleto.
Um img com largura intrínseca enorme estoura a coluna se faltar max-width: 100%. O capítulo 32 já mostrou. Aqui é o teste: 320 px, foto da orla, sem barra horizontal.
Mude .wrap para width: 70rem sem min(). Preveja o corte. Recarregue. Volte ao min().
Zoom é tela pequena também
Ampliar o tipo para 200% estreita a coluna útil. Mobile first já treinou isso: a página não depende de uma largura mágica em pixels. Queries em rem (capítulo 38) reagem ao zoom melhor que px.
overflow-x: hidden no body esconde o problema em vez de corrigir. Ache o elemento largo demais. Costuma ser imagem sem max-width, ou um pre de código, ou um width fixo.
Toque: espaço entre links do menu. padding: 0.5rem 0.75rem no a aumenta a área. O exemplo da Oficina já usa gap no flex.
Copie um width: 110% num filho. Preveja a barra horizontal. Recarregue. Remova.
min-height: 100vh no body pode criar scroll fantasma no telefone, por causa da barra do navegador. Prefira o fluxo natural. Não lute com a barra usando overflow escondido.

Atividades
- O que
width=device-widthno viewport impede o telefone de fazer? - Por que
width: 960pxnobodyquebra a tela pequena? - O menu da Oficina some no telefone neste volume? Justifique.
- Qual função CSS limita a coluna a
70reme à janela ao mesmo tempo? - Media query de
max-widthé o primeiro passo do mobile first? - Por que
overflow-x: hiddennobodyé má resposta para a barra horizontal?
Respostas comentadas
- Impede fingir uma tela larga e reduzir a página inteira a miniatura.
- A caixa é mais larga que o aparelho. Aparece scroll horizontal e o texto encolhe se houver viewport errado.
- Não. O menu quebra linha com Flexbox. Destinos continuam no HTML e na tela.
min(70rem, calc(100% - 2rem)).- Não. Primeiro a coluna estreita sem query.
min-widthentra depois para ampliar. - Esconde o excesso em vez de achar o elemento largo. O conteúdo cortado some do zoom e do teclado.
Referências
O arquivo completo
Referência do exemplo 37-tela-pequena, reproduzida aqui para que você possa conferir sem sair da página.
assets/javascript/simulacao.js
const form=document.querySelector("#simulacao");if(form){form.querySelector("button[type=submit]").disabled=false;form.addEventListener("submit",event=>{event.preventDefault();document.querySelector("#retorno").textContent="Simulação concluída. Nada foi enviado ou guardado.";});}