Como fazer um site responsivo CSS
Abra o seu site no celular. Se o texto aparece minúsculo, se você precisa dar zoom com dois dedos para ler, ou se a página rola para os lados, o site não é responsivo. E isso pesa: hoje a maior parte dos acessos na internet vem do celular, e o Google usa a versão mobile do site como referência para posicionar as páginas na busca.
Neste artigo vamos construir, passo a passo, um site que se adapta sozinho ao tamanho da tela: duas colunas no computador, uma coluna no tablet e um menu empilhado no celular, com direito a um banner diferente para cada tamanho. Tudo com HTML e CSS puros.
O que é um site responsivo?
Um site responsivo é aquele que reorganiza o próprio layout de acordo com a largura da tela. Não existe uma versão “para celular” e outra “para computador”: é o mesmo HTML, e o CSS decide como mostrar cada parte em cada tamanho.
Para chegar nesse resultado, precisamos de três ingredientes:
Ingrediente 1: a meta tag viewport
Sem nenhuma instrução, o navegador do celular finge que a tela tem uns 980px de largura, desenha a página nesse tamanho e depois encolhe tudo para caber. Resultado: um site em miniatura, com texto ilegível. A linha abaixo, dentro do <head>, desliga esse comportamento:
<meta name="viewport" content="width=device-width, initial-scale=1">width=device-width: a largura da página é a largura real do aparelho.initial-scale=1: a página abre sem zoom, em tamanho 100%.
A estrutura do nosso exemplo
O site de exemplo tem cinco blocos, usando tags semânticas, que dizem ao navegador (e ao Google) o papel de cada parte:
<header class="cabecalho"> ... </header> <!-- banner com o título -->
<nav class="barra_nav"> ... </nav> <!-- menu -->
<div class="coluna">
<aside class="lateral"> ... </aside> <!-- coluna da esquerda (30%) -->
<main class="principal"> ... </main> <!-- conteúdo principal (70%) -->
</div>
<footer class="rodape"> ... </footer> <!-- rodapé -->A <div class="coluna"> é uma caixa que envolve as duas colunas. É nela que o flexbox vai agir.
Ingrediente 2: layout flexível com flexbox
O flexbox é um modo de layout do CSS feito para organizar elementos em linha ou em coluna. Ele funciona sempre em dupla: um container (a caixa de fora) e seus itens (as caixas de dentro).
display: flex — os filhos lado a lado
Por padrão, blocos como <aside> e <main> ficam um embaixo do outro. Quando o container recebe display: flex, os filhos passam a ficar lado a lado:
.coluna {
display: flex; /* os filhos ficam lado a lado */
flex-wrap: wrap; /* se não couberem, quebram para a linha de baixo */
}flex: 30% e 70% — a largura de cada coluna
Nos itens, a propriedade flex define o tamanho de cada um. Usamos porcentagem, e não pixels, para que as colunas se ajustem a qualquer largura de tela:
.lateral {
flex: 30%; /* a lateral ocupa 30% da largura */
}
.principal {
flex: 70%; /* o conteúdo ocupa 70% */
}flex-direction: column, os mesmos itens passam a ficar um embaixo do outro.flex-direction — linha ou coluna?
Essa é a propriedade-chave para a responsividade. Ela define a direção em que os itens são organizados:
flex-direction: row(padrão): itens lado a lado, em linha.flex-direction: column: itens um embaixo do outro, em coluna.
No computador queremos row e no celular, column. Para trocar uma pela outra dependendo do tamanho da tela, usamos o terceiro ingrediente.
Ingrediente 3: media queries (@media)
Uma media query é um bloco de CSS com uma condição: as regras dentro dela só valem quando a condição é verdadeira. A condição mais usada é a largura da tela:
max-width ou min-width?
max-width: 768pxsignifica “até 768px”: vale para telas de 768px ou menos.min-width: 768pxsignifica “a partir de 768px”: vale para telas de 768px ou mais.
No nosso exemplo usamos max-width: escrevemos o CSS pensando no computador e depois ajustamos para as telas menores. O caminho inverso, com min-width, se chama mobile first (primeiro o celular) e é assunto para um próximo artigo.
Os pontos de quebra (breakpoints)
Os valores de largura em que o layout muda se chamam breakpoints. Não existe um número mágico, mas alguns são bem comuns:
| Breakpoint | Aparelhos típicos |
|---|---|
até 500px | Celulares em pé |
até 768px | Tablets em pé e celulares deitados |
até 1024px | Tablets deitados e notebooks pequenos |
acima de 1024px | Notebooks e monitores |
As duas media queries do exemplo
Nosso site usa dois breakpoints, cada um resolvendo um problema:
/* Tablets e celulares (até 768px): colunas empilhadas */
@media screen and (max-width: 768px) {
.coluna {
flex-direction: column;
}
}
/* Celulares (até 500px): menu empilhado e banner próprio */
@media screen and (max-width: 500px) {
.barra_nav {
flex-direction: column;
}
.cabecalho {
background-image: url(../imagem/banner_celular_420x250.png);
}
}Repare que a tela de 400px atende às duas condições (é menor que 768px e menor que 500px), então as duas media queries valem ao mesmo tempo. Já uma tela de 700px só atende à primeira.
Trocando o banner conforme a tela
Um banner largo, de 1500×500, fica lindo no computador. No celular, porém, ele seria cortado e perderia os detalhes das laterais. A solução é trocar a imagem de fundo dentro da media query. Só a propriedade background-image precisa ser repetida: o resto (background-size, color etc.) continua valendo da regra original.
.cabecalho {
padding: 60px 20px;
text-align: center;
color: white;
background-color: #0a1128; /* reserva, caso a imagem não carregue */
background-image: url(../imagem/banner_responsivo.png);
background-size: cover; /* cobre toda a área, sem distorcer */
background-position: center; /* centraliza o recorte */
}../ no caminho? O caminho da imagem é contado a partir do arquivo CSS, e não do HTML. Como o styles.css está dentro da pasta css/, o ../ sobe um nível antes de entrar na pasta imagem/.Teste aqui: arraste e veja o layout mudar
A miniatura abaixo reproduz o nosso site. Arraste o canto inferior direito da moldura para a esquerda e veja as colunas se empilharem e, depois, o menu também.
No celular, gire a tela ou abra o artigo no computador para testar.
Como testar no navegador (sem precisar de celular)
- Abra o seu
index.htmlno Chrome, Edge ou Firefox. - Aperte F12 para abrir as ferramentas do desenvolvedor.
- Aperte Ctrl + Shift + M (ou clique no ícone de celular e tablet) para ativar o modo dispositivo.
- Escolha um aparelho na lista do topo (iPhone, Galaxy, iPad…) ou arraste as bordas para testar qualquer largura.
O jeito mais simples continua valendo: diminuir a janela do navegador com o mouse. Por isso o exemplo tem a faixa amarela no topo com esse lembrete.
Erros comuns
No computador tudo funciona; no celular, o site aparece em miniatura. Confira se a linha <meta name="viewport" ...> está no <head>.
Se a regra normal vier depois da media query, ela sobrescreve a media query (as duas têm a mesma força, e vence a última). Deixe as media queries sempre no final do arquivo.
Uma coluna com width: 400px não cabe numa tela de 360px e cria uma rolagem para os lados. Prefira porcentagem e, para imagens, max-width: 100%.
O caminho é contado a partir do arquivo CSS. Se o banner não aparecer, confira o ../ e o nome exato do arquivo (maiúsculas, minúsculas e extensão).
and@media screen and(max-width: 768px), sem o espaço antes do parêntese, faz o navegador ignorar a media query inteira. O certo é and (max-width: 768px).
Código completo do exemplo
Monte a pasta assim e abra o index.html no navegador:
site-responsivo/
├── index.html
├── css/
│ └── styles.css
└── imagem/
├── banner_responsivo.png (1500 × 500)
└── banner_celular_420x250.png (420 × 250)index.html<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Site Responsivo</title>
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<!-- Anotação -->
<div class="anotacao">
<p>Diminua a janela do navegador para ver o efeito de responsividade.</p>
</div>
<!-- Cabeçalho -->
<header class="cabecalho">
<h1>Site Responsivo Mobile/Desktop</h1>
<p>Com <b>layout</b> responsivo.</p>
</header>
<!-- Barra de navegação -->
<nav class="barra_nav">
<a href="#">Início</a>
<a href="#">Página 2</a>
<a href="#">Página 3</a>
<a href="#">Página 4</a>
</nav>
<!-- Layout flexível (conteúdo) -->
<div class="coluna">
<aside class="lateral">
<h2>Sobre mim</h2>
<p class="legenda">Foto:</p>
<div class="imagem_falsa">Imagem</div>
<p>Algum texto genérico para marcar o espaço utilizado no parágrafo.</p>
<h3>Mais texto</h3>
<p>Algum texto genérico para marcar o espaço utilizado no parágrafo.</p>
<div class="imagem_falsa2">Imagem</div>
<div class="imagem_falsa2">Imagem</div>
<div class="imagem_falsa2">Imagem</div>
</aside>
<main class="principal">
<article>
<h2>TÍTULO DO TEXTO</h2>
<p class="legenda">Texto descritivo, 17 de março de 2023</p>
<div class="imagem_falsa3">Imagem</div>
<h3>Mais texto</h3>
<p>Algum texto genérico para marcar o espaço utilizado no parágrafo.</p>
</article>
<article>
<h2>TÍTULO DO TEXTO</h2>
<p class="legenda">Texto descritivo, 16 de março de 2023</p>
<div class="imagem_falsa3">Imagem</div>
<h3>Mais texto</h3>
<p>Algum texto genérico para marcar o espaço utilizado no parágrafo.</p>
</article>
</main>
</div>
<!-- Rodapé -->
<footer class="rodape">
<p>Seu Nome ©</p>
</footer>
</body>
</html>css/styles.css* {
box-sizing: border-box;
}
/* Estilo do body */
body {
font-family: Arial, sans-serif;
margin: 0;
}
.anotacao {
background-color: rgb(244, 248, 19);
padding: 5px;
text-align: center;
font-weight: bold;
}
.anotacao p {
margin: 8px 0;
}
/* Cabeçalho */
.cabecalho {
padding: 60px 20px;
text-align: center;
color: white;
background-color: #0a1128; /* reserva, caso a imagem não carregue */
background-image: url(../imagem/banner_responsivo.png);
background-size: cover;
background-position: center;
}
/* Barra de navegação: links lado a lado */
.barra_nav {
display: flex;
background-color: #333;
}
.barra_nav a {
color: white;
padding: 14px 20px;
text-decoration: none;
text-align: center;
}
/* Trocar a cor quando o cursor estiver sobre o link */
.barra_nav a:hover {
background-color: #ddd;
color: black;
}
/* Contorno para quem navega pelo teclado */
.barra_nav a:focus-visible {
outline: 3px solid #f68e36;
outline-offset: -3px;
}
/* Coluna: as duas colunas lado a lado */
.coluna {
display: flex;
flex-wrap: wrap;
}
/* Barra lateral: 30% da largura */
.lateral {
flex: 30%;
background-color: #f1f1f1;
padding: 20px;
}
/* Coluna principal: 70% da largura */
.principal {
flex: 70%;
background-color: white;
padding: 20px;
}
.legenda {
font-size: 13px;
font-weight: bold;
}
/* Imagens falsas, apenas para marcar o espaço */
.imagem_falsa {
background-color: #0ec40e7e;
width: 100%;
height: 200px;
padding: 20px;
}
.imagem_falsa2 {
background-color: #c7313191;
width: 100%;
height: 60px;
padding: 20px;
margin-bottom: 16px;
}
.imagem_falsa3 {
background-color: #313bc777;
width: 100%;
height: 200px;
padding: 20px;
}
/* Rodapé */
.rodape {
padding: 20px;
text-align: center;
background-color: #ddd;
font-size: 22px;
font-weight: bold;
}
/* ===== RESPONSIVIDADE ===== */
/* Tablets e celulares (até 768px): as colunas ficam uma embaixo da outra */
@media screen and (max-width: 768px) {
.coluna {
flex-direction: column;
}
}
/* Celulares (até 500px): menu empilhado e banner próprio para tela pequena */
@media screen and (max-width: 500px) {
.barra_nav {
flex-direction: column;
}
.cabecalho {
background-image: url(../imagem/banner_celular_420x250.png);
}
}Resumo rápido
| Recurso | Para que serve |
|---|---|
<meta name="viewport"> | Faz o celular usar a largura real da tela |
display: flex | Coloca os filhos do container lado a lado |
flex-wrap: wrap | Deixa os itens quebrarem de linha quando não cabem |
flex: 30% | Define o tamanho do item em relação ao container |
flex-direction: column | Empilha os itens um embaixo do outro |
@media (max-width: 768px) | Aplica regras só em telas de até 768px |
Desafio para praticar
- Monte o projeto com a estrutura de pastas acima e teste nas três larguras: computador, tablet (700px) e celular (400px).
- Crie uma terceira media query, para telas de até
400px, que diminua o tamanho doh1do cabeçalho. - Mude as proporções das colunas para 25% e 75%. O que acontece com a lateral no computador?
- Apague a meta viewport, abra o site no seu celular e compare. Depois, coloque-a de volta.
- Desafio extra: faça os links do menu ocuparem a mesma largura no computador, adicionando
flex: 1em.barra_nav a.
Washington Paiva — instrutor de Desenvolvimento de Sistemas · washington.pro.br
Compartilhe:



Publicar comentário