Pular para o conteúdo
murad.guide

A Web Aberta

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

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.

Resumo dos conceitos: 320px, coluna única, toque

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.

Resumo dos conceitos: toque, coluna única, 320px

Atividades

  1. O que width=device-width no viewport impede o telefone de fazer?
  2. Por que width: 960px no body quebra a tela pequena?
  3. O menu da Oficina some no telefone neste volume? Justifique.
  4. Qual função CSS limita a coluna a 70rem e à janela ao mesmo tempo?
  5. Media query de max-width é o primeiro passo do mobile first?
  6. Por que overflow-x: hidden no body é má resposta para a barra horizontal?

Respostas comentadas

  1. Impede fingir uma tela larga e reduzir a página inteira a miniatura.
  2. A caixa é mais larga que o aparelho. Aparece scroll horizontal e o texto encolhe se houver viewport errado.
  3. Não. O menu quebra linha com Flexbox. Destinos continuam no HTML e na tela.
  4. min(70rem, calc(100% - 2rem)).
  5. Não. Primeiro a coluna estreita sem query. min-width entra depois para ampliar.
  6. 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.";});}