Mobile-first com Flexbox e Grid

Arquitetura responsiva com menu adaptável, grade de colunas e composição completa de página

Por Fábio Linhares • Instituto Infnet

Como usar esta página

Este material é sobre layout responsivo com método. O foco não é estado de componente: é construir estrutura, aplicar regras por contexto e prever comportamento sem depender de tentativa e erro.

O núcleo da solução está em quatro frentes: menu mobile-first com Flexbox, adaptação por media queries, grade em 12 colunas e composição final com banner full width e rodapé distribuído.

Como referência operacional, os exemplos usam 768px para tablet e 1024px para desktop. Se sua turma usar outros tamanhos, troque os valores e mantenha a mesma lógica de progressão com min-width.

A forma mais segura de executar é montar uma página única integrada: header com menu, banner de destaque, área principal em grid e footer com menu lateral e redes sociais no lado oposto.

  • Flexbox para alinhamento e distribuição em um eixo.
  • Grid para organização em linhas e colunas.
  • Media query para mudança controlada de comportamento.
  • Container para conteúdo e full width para banner.
  • Execução integrada: header, banner, grid e footer.
EXERCÍCIO 01
Estrutura-base da página
Objetivo: organizar HTML semântico em header, banner, conteúdo e footer.

Comece pela arquitetura da página. A separação por blocos reduz acoplamento de CSS e facilita depuração quando o layout troca de estado entre mobile, tablet e desktop.

O que o enunciado pede
1. Cabeçalho com menu adaptável e elementos de identidade.
2. Banner ocupando largura total da viewport.
3. Área de tópicos responsiva em sistema de colunas.
4. Rodapé com menu de um lado e redes sociais no lado oposto.
<!-- index.html -->
<header class="site-header">
  <div class="container">
    <input type="checkbox" id="nav-toggle" class="nav-toggle" />
    <div class="topbar">
      <label for="nav-toggle" class="hamburger">☰</label>
      <div class="logo">MinhaLogo</div>
      <div class="social social-header">
        <a href="#">FB</a><a href="#">IG</a><a href="#">YT</a>
      </div>
    </div>
    <nav class="main-nav">
      <a href="#">Home</a><a href="#">Cursos</a><a href="#">Projetos</a><a href="#">Contato</a>
    </nav>
  </div>
</header>

<section class="banner"><div class="banner-content"><h1>Banner</h1></div></section>

<main class="container">
  <section class="row topics">
    <article class="col-12 col-md-6 col-lg-3 topic-card">Tópico 1</article>
    <article class="col-12 col-md-6 col-lg-3 topic-card">Tópico 2</article>
    <article class="col-12 col-md-6 col-lg-3 topic-card">Tópico 3</article>
    <article class="col-12 col-md-6 col-lg-3 topic-card">Tópico 4</article>
  </section>
</main>

<footer class="site-footer">
  <div class="container footer-wrap">
    <nav class="footer-menu"><a href="#">Sobre</a><a href="#">Contato</a></nav>
    <div class="footer-spacer"></div>
    <div class="social social-footer"><a href="#">FB</a><a href="#">IG</a><a href="#">YT</a></div>
  </div>
</footer>
Como validar
1. Com CSS desligado, a hierarquia semântica continua legível.
2. Header, banner, conteúdo e footer aparecem como blocos distintos.
Como explicar
Estruturei primeiro as quatro áreas principais da página e só depois refinei o estilo por bloco.
EXERCÍCIO 02
Menu com Flexbox e hamburger no mobile
Objetivo: alinhar topo com Flexbox e controlar menu colapsável no layout base.
O que o enunciado pede
Menu mobile-first com botão hamburger para exibir/ocultar navegação.
Logo no cabeçalho e ícones sociais no mesmo bloco superior.
<!-- index.html -->
<input type="checkbox" id="nav-toggle" class="nav-toggle" />
<div class="topbar">
  <label for="nav-toggle" class="hamburger">☰</label>
  <div class="logo">MinhaLogo</div>
  <div class="social social-header"><a href="#">FB</a><a href="#">IG</a><a href="#">YT</a></div>
</div>
<nav class="main-nav"><a href="#">Home</a><a href="#">Cursos</a><a href="#">Projetos</a><a href="#">Contato</a></nav>

/* styles.css */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.nav-toggle { display: none; }

.main-nav {
  display: none;
  flex-direction: column;
  gap: .75rem;
  margin-top: 1rem;
}

.nav-toggle:checked ~ .main-nav {
  display: flex;
}
Como validar
1. Em largura pequena, o menu inicia fechado.
2. Ao alternar o checkbox, a navegação passa a aparecer em coluna.
Como explicar
Usei Flexbox para alinhar o topo em um eixo e controlei a visibilidade do menu por estado do checkbox.
No mobile, mantenha o fluxo simples: botão hamburger visível, menu fechado por padrão e logo com prioridade visual.
Evite resolver esse topo com posicionamento absoluto sem necessidade; Flexbox já cobre o problema com menos fragilidade.
EXERCÍCIO 03
Media queries e responsividade do menu
Objetivo: evoluir o layout com min-width, reposicionando logo e redes sociais.
O que o enunciado pede
Criar breakpoints para tablet e desktop.
Reorganizar logo, menu e redes sociais em telas maiores.
@media (min-width: 768px) {
  .main-nav {
    display: flex;
    flex-direction: row;
    gap: 1rem;
  }
}

@media (min-width: 1024px) {
  .site-header .container {
    display: flex;
    align-items: center;
    gap: 2rem;
  }

  .topbar { display: contents; }
  .hamburger { display: none; }

  .logo {
    margin-inline: 0;
    order: 1;
  }

  .main-nav {
    margin-top: 0;
    order: 2;
  }

  .social-header {
    order: 3;
    margin-left: auto;
  }
}
display: contents é opcional. Ele simplifica a distribuição dos elementos no desktop, mas pode ser substituído por outra estrutura equivalente.
Como validar
1. 360px: hamburger ativo e menu colapsado.
2. 768px: navegação mais distribuída.
3. 1024px: logo à esquerda, menu no centro e redes à direita.
Como explicar
O layout nasce no mobile e evolui com min-width, mudando só o necessário em cada faixa de largura.
EXERCÍCIO 04
Container, row e grade de 12 colunas
Objetivo: aplicar sistema de colunas inspirado em Bootstrap para cards responsivos.
O que o enunciado pede
Regra de container, regra de row e colunas no padrão de 12 partes.
Aplicação do sistema de colunas em pelo menos 4 itens.
<!-- index.html -->
<section class="row topics">
  <article class="col-12 col-md-6 col-lg-3 topic-card">Tópico 1</article>
  <article class="col-12 col-md-6 col-lg-3 topic-card">Tópico 2</article>
  <article class="col-12 col-md-6 col-lg-3 topic-card">Tópico 3</article>
  <article class="col-12 col-md-6 col-lg-3 topic-card">Tópico 4</article>
</section>

/* styles.css */
.container {
  width: min(1120px, calc(100% - 2rem));
  margin-inline: auto;
}

.row {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 1rem;
}

.col-12 { grid-column: span 12; }

@media (min-width: 768px) {
  .col-md-6 { grid-column: span 6; }
}

@media (min-width: 1024px) {
  .col-lg-3 { grid-column: span 3; }
}
Como validar
1. Mobile: cada card ocupa 12/12.
2. Tablet: cada card ocupa 6/12.
3. Desktop: cada card ocupa 3/12.
Como explicar
A grade de 12 colunas permite reutilizar classes de largura por breakpoint sem fixar pixel em cada item.
Não aplique container no banner. O banner é full width; o conteúdo principal é contido.
EXERCÍCIO 05
Banner 100% da largura, 4 tópicos e rodapé distribuído
Objetivo: integrar banner full width, cards em grade e footer com menu lateral + redes no lado oposto.
O que o enunciado pede
Banner ocupando 100% da largura visível.
Quatro tópicos responsivos e rodapé distribuído com menu vertical + redes sociais.
<!-- index.html -->
<section class="banner">
  <div class="banner-content"><h1>Banner principal</h1></div>
</section>

<main class="container">
  <section class="row topics">
    <article class="col-12 col-md-6 col-lg-3 topic-card">Tópico 1</article>
    <article class="col-12 col-md-6 col-lg-3 topic-card">Tópico 2</article>
    <article class="col-12 col-md-6 col-lg-3 topic-card">Tópico 3</article>
    <article class="col-12 col-md-6 col-lg-3 topic-card">Tópico 4</article>
  </section>
</main>

<footer class="site-footer">
  <div class="container footer-wrap">
    <nav class="footer-menu"><a href="#">Sobre</a><a href="#">Contato</a></nav>
    <div class="footer-spacer"></div>
    <div class="social social-footer"><a href="#">FB</a><a href="#">IG</a><a href="#">YT</a></div>
  </div>
</footer>

/* styles.css */
.banner {
  width: 100%;
  min-height: 40vh;
  display: grid;
  place-items: center;
  text-align: center;
  color: #fff;
  background: linear-gradient(135deg, #4f46e5, #0ea5e9);
  padding: 2rem;
}

.topic-card {
  background: #f2f2f2;
  border: 1px solid #ddd;
  border-radius: 12px;
  padding: 1rem;
  min-height: 140px;
}

.footer-wrap {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.footer-menu {
  display: flex;
  flex-direction: column;
  gap: .5rem;
}

@media (min-width: 768px) {
  .footer-wrap {
    flex-direction: row;
    align-items: flex-start;
  }

  .footer-spacer {
    display: block;
    flex: 1;
  }
}
Como validar
1. Mobile: cards em 1 coluna (12/12).
2. Tablet: cards em 2 colunas (6/12).
3. Desktop: cards em 4 colunas (3/12).
4. Rodapé com menu de um lado, redes sociais do outro e área central livre.
Como explicar
Banner fica fora do container para manter full width; tópicos e footer interno usam container para preservar leitura.
EXERCÍCIO 06
CSS final integrado
Objetivo: consolidar as regras principais em um único arquivo coerente.
O que o enunciado pede
Consolidar o layout completo em um CSS único, preservando comportamento responsivo.
/* styles.css */
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body { font-family: Arial, sans-serif; line-height: 1.5; color: #111; }

.container { width: min(1120px, calc(100% - 2rem)); margin-inline: auto; }
.site-header { background: #111; color: #fff; padding: 1rem 0; }
.nav-toggle { display: none; }
.topbar { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.main-nav { display: none; flex-direction: column; gap: .75rem; margin-top: 1rem; }
.nav-toggle:checked ~ .main-nav { display: flex; }

.banner {
  width: 100%;
  min-height: 40vh;
  display: grid;
  place-items: center;
  text-align: center;
  color: #fff;
  background: linear-gradient(135deg, #4f46e5, #0ea5e9);
  padding: 2rem;
}

.row { display: grid; grid-template-columns: repeat(12, 1fr); gap: 1rem; }
.col-12 { grid-column: span 12; }

.topic-card {
  background: #f2f2f2;
  border: 1px solid #ddd;
  border-radius: 12px;
  padding: 1rem;
  min-height: 140px;
}

.site-footer { margin-top: 2rem; background: #111; color: #fff; padding: 1.5rem 0; }
.footer-wrap { display: flex; flex-direction: column; gap: 1rem; }
.footer-menu { display: flex; flex-direction: column; gap: .5rem; }
.footer-spacer { display: none; }

@media (min-width: 768px) {
  .main-nav { display: flex; flex-direction: row; gap: 1rem; }
  .col-md-6 { grid-column: span 6; }
  .footer-wrap { flex-direction: row; align-items: flex-start; }
  .footer-spacer { display: block; flex: 1; }
}

@media (min-width: 1024px) {
  .site-header .container { display: flex; align-items: center; gap: 2rem; }
  .topbar { display: contents; }
  .hamburger { display: none; }
  .logo { margin-inline: 0; order: 1; }
  .main-nav { margin-top: 0; order: 2; }
  .social-header { order: 3; margin-left: auto; }
  .col-lg-3 { grid-column: span 3; }
}
Como validar
Verifique em 360px, 768px e 1024px se header, cards e footer trocam de estado como esperado.
Como explicar
Este bloco reúne toda a cadeia de layout: base mobile, progressão por breakpoint e composição final completa.
EXERCÍCIO 07
Como defender a solução de forma técnica
Objetivo: explicar escolhas de layout com clareza e sem ambiguidade.

Uma defesa técnica consistente segue uma cadeia simples: condição, regra aplicada e comportamento observado. Exemplo: “no layout base priorizei mobile; em min-width reorganizei cabeçalho para distribuição horizontal estável; usei Grid para os tópicos porque há malha de colunas”.

Roteiro de explicação em 3 frases
1. O layout nasce mobile-first com menu colapsável para reduzir complexidade inicial.
2. Flexbox resolve header/footer por alinhamento em uma dimensão.
3. Grid resolve os tópicos por distribuição em 12 colunas com breakpoints progressivos.
EXERCÍCIO 08
Erros recorrentes e competências finais
Objetivo: consolidar critérios de qualidade para evoluir do ajuste visual para engenharia de layout.
Erros recorrentes: banner dentro do container, menu horizontal no mobile, cards com largura fixa em pixels, breakpoints sem propósito e uso de ferramenta inadequada para o tipo de problema.
Competências finais: leitura técnica de requisitos, HTML semântico com arquitetura previsível, domínio prático de Flexbox e Grid, e capacidade de evoluir layout por media queries com justificativa objetiva.