Domine as técnicas essenciais de design responsivo para criar interfaces que se adaptam a qualquer dispositivo. Aprenda abordagens mobile-first, media queries e estratégias flexíveis para uma web verdadeiramente universal.
Entender os princípios fundamentais do design responsivo e sua importância na web moderna.
Aprender a usar media queries para adaptar seu layout a diferentes tamanhos de tela e dispositivos.
Implementar a abordagem mobile-first no desenvolvimento de interfaces e compreender seus benefícios.
Design Responsivo é uma abordagem de desenvolvimento web que faz com que as páginas se adaptem automaticamente ao tamanho da tela e às características do dispositivo onde estão sendo visualizadas. Não se trata apenas de encolher ou expandir elementos, mas de proporcionar a melhor experiência de usuário possível em qualquer contexto.
Era | Abordagem | Problemas |
---|---|---|
Início da Web | Design fixo (não-responsivo) | Sites otimizados apenas para telas de desktop |
Surgimento dos Smartphones | Sites mobile separados (m.exemplo.com) | Duplicação de conteúdo, manutenção dupla, problemas de SEO |
2010+ | Design responsivo (adaptável) | Curva de aprendizado, desafios de performance |
Hoje | Design responsivo + abordagem mobile-first | Complexidade crescente, mas ferramentas melhores |
Uso de unidades relativas (%, em, rem) em vez de unidades absolutas (px) para que o layout se expanda e contraia naturalmente.
Imagens que se redimensionam dentro de seus elementos contêineres, mantendo a proporção e otimizando para diferentes resoluções.
Regras CSS que são aplicadas apenas quando determinadas condições de mídia são atendidas, como largura da tela ou orientação do dispositivo.
Media queries são a ferramenta mais poderosa do CSS para implementar design responsivo. Elas permitem aplicar estilos condicionalmente com base em características do dispositivo, como largura da tela, altura, resolução, orientação e muito mais.
@media tipo-de-midia and (caracteristica: valor) {
/* Regras CSS que serão aplicadas quando a condição for verdadeira */
seletor {
propriedade: valor;
}
}
all
- Para todos os dispositivos (padrão)screen
- Para telas de computador, tablet, smartphone, etc.print
- Para documentos a serem impressosspeech
- Para leitores de telaCaracterística | Descrição | Exemplo |
---|---|---|
width | Largura da viewport | @media (width: 768px) {...} |
min-width | Largura mínima da viewport | @media (min-width: 768px) {...} |
max-width | Largura máxima da viewport | @media (max-width: 767px) {...} |
height | Altura da viewport | @media (height: 480px) {...} |
orientation | Orientação do dispositivo | @media (orientation: landscape) {...} |
aspect-ratio | Proporção da viewport | @media (aspect-ratio: 16/9) {...} |
resolution | Densidade de pixels | @media (min-resolution: 192dpi) {...} |
/* AND: Ambas as condições devem ser verdadeiras */
@media screen and (min-width: 768px) and (max-width: 1023px) {
/* Estilos para tablets */
}
/* OR: Pelo menos uma condição deve ser verdadeira (use vírgulas) */
@media screen and (max-width: 767px), screen and (orientation: portrait) {
/* Estilos para dispositivos pequenos OU em orientação retrato */
}
/* NOT: Inverte a condição */
@media not screen and (min-width: 1024px) {
/* Estilos para todos os dispositivos EXCETO desktops grandes */
}
/* ONLY: Previne navegadores antigos de aplicarem os estilos */
@media only screen and (min-width: 768px) {
/* Estilos para navegadores modernos */
}
Breakpoints são os pontos de largura onde o layout muda significativamente. Embora não existam breakpoints universais (pois dependem do seu design), alguns valores são comumente usados:
/* Mobile pequeno (até 320px) */
@media (max-width: 320px) {
/* Estilos para smartphones muito pequenos */
}
/* Mobile (até 480px) */
@media (max-width: 480px) {
/* Estilos para smartphones */
}
/* Mobile grande / Tablet pequeno (até 767px) */
@media (max-width: 767px) {
/* Estilos para smartphones grandes ou tablets pequenos */
}
/* Tablets (768px - 1023px) */
@media (min-width: 768px) and (max-width: 1023px) {
/* Estilos para tablets */
}
/* Laptops / Desktops pequenos (1024px - 1199px) */
@media (min-width: 1024px) and (max-width: 1199px) {
/* Estilos para laptops e desktops pequenos */
}
/* Desktops grandes (1200px+) */
@media (min-width: 1200px) {
/* Estilos para telas grandes */
}
Em vez de tentar acomodar cada dispositivo específico, concentre-se em onde seu design naturalmente "quebra" e precisa de ajustes. Isso torna seu código mais sustentável diante da constante evolução dos dispositivos.
Mobile-First é uma estratégia de design e desenvolvimento onde você cria primeiro a versão móvel do site (para telas menores) e depois progressivamente adiciona complexidade e recursos para telas maiores. É o oposto da abordagem tradicional Desktop-First.
Abordagem Desktop-First | Abordagem Mobile-First |
---|---|
|
|
Garanta que a página seja exibida corretamente em dispositivos móveis.
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Prefira rem, em, % ao invés de pixels fixos.
/* Evite isso */
p {
font-size: 16px;
margin-bottom: 24px;
}
/* Prefira isso */
html {
font-size: 16px; /* Base para cálculos rem */
}
p {
font-size: 1rem;
margin-bottom: 1.5rem;
}
Comece com estilos base para mobile e use min-width
para telas maiores.
/* Estilos base (mobile) */
.nav-menu {
display: flex;
flex-direction: column;
}
/* Tablet em diante */
@media (min-width: 768px) {
.nav-menu {
flex-direction: row;
}
}
Use padrões como menus hamburger em telas pequenas.
Use técnicas como imagens responsivas e estratégias de carregamento lazy.
<img
srcset="imagem-pequena.jpg 480w,
imagem-media.jpg 768w,
imagem-grande.jpg 1200w"
sizes="(max-width: 480px) 100vw,
(max-width: 768px) 50vw,
33vw"
src="imagem-fallback.jpg"
alt="Descrição da imagem"
loading="lazy"
>
Usar as unidades corretas é fundamental para criar layouts verdadeiramente responsivos. Unidades relativas permitem que seu layout se adapte e dimensione proporcionalmente em diferentes tamanhos de tela.
Unidades Estáticas | Unidades Relativas |
---|---|
px - Pixels absolutos |
% - Porcentagem relativa ao elemento pai |
pt - Pontos (usado para impressão) |
em - Relativo ao tamanho da fonte do elemento |
cm , mm - Medidas físicas |
rem - Relativo ao tamanho da fonte do elemento raiz (html) |
pc , in - Picas, polegadas |
vw , vh - Percentual da largura/altura da viewport |
Melhor para: Bordas, sombras, pequenos detalhes visuais que não precisam escalar.
border: 1px solid #ccc;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
Melhor para: Tipografia, margens, padding, manter consistência em todo o site.
html { font-size: 16px; }
h1 { font-size: 2rem; } /* 32px */
p { font-size: 1rem; margin: 1.5rem 0; }
Melhor para: Elementos que devem escalar em relação ao seu contexto direto.
.card { font-size: 1.1rem; }
.card .title {
font-size: 1.4em; /* Relativo a 1.1rem */
}
.card small {
font-size: 0.8em; /* Relativo a 1.1rem */
}
Melhor para: Layouts, larguras de colunas e elementos que precisam se redimensionar com o contêiner.
.container { width: 100%; max-width: 1200px; }
.sidebar { width: 30%; }
.content { width: 70%; }
Melhor para: Elementos de página inteira, heroes, banners que ocupam porcentagem da viewport.
.hero {
height: 100vh; /* Altura total da viewport */
}
.large-text {
font-size: 5vw; /* 5% da largura da viewport */
}
Melhor para: Combinação de unidades diferentes ou valores dinâmicos.
.sidebar {
width: calc(100% - 2rem); /* 100% menos 2rem */
}
.hero-title {
font-size: calc(1.5rem + 3vw); /* Base + escala */
}
Combinando calc()
com unidades relativas, você pode criar uma escala de fonte que aumenta suavemente conforme o tamanho da tela:
:root {
/* Tamanho base: 16px em mobile, escalando até ~18px em desktop */
--fs-base: calc(1rem + 0.25vw);
/* Escala de tipografia usando a base */
--fs-small: calc(var(--fs-base) * 0.8);
--fs-body: var(--fs-base);
--fs-h3: calc(var(--fs-base) * 1.2);
--fs-h2: calc(var(--fs-base) * 1.5);
--fs-h1: calc(var(--fs-base) * 2.5);
}
body { font-size: var(--fs-body); }
h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }
/* etc. */
Ao longo dos anos, certos padrões de design provaram ser eficazes para resolver problemas comuns de responsividade. Conhecer esses padrões pode acelerar seu desenvolvimento e melhorar a experiência do usuário.
.container {
width: 100%;
max-width: 1200px;
margin-left: auto;
margin-right: auto;
padding-left: 15px;
padding-right: 15px;
}
Este padrão permite que o conteúdo use toda a largura disponível em telas pequenas, mas impede que fique muito largo em telas grandes, melhorando a legibilidade.
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
}
Este padrão moderno usa CSS Grid para criar uma grade que automaticamente se ajusta ao número de colunas com base no espaço disponível. Cada item tem no mínimo 300px de largura e compartilha o espaço igualmente.
/* Estilo base - menu escondido em mobile */
.nav-menu {
display: none;
}
.menu-toggle {
display: block; /* Botão de hambúrguer visível */
}
/* Menu visível em desktop */
@media (min-width: 768px) {
.nav-menu {
display: flex;
}
.menu-toggle {
display: none; /* Oculta o botão em desktop */
}
}
document.querySelector('.menu-toggle').addEventListener('click', function() {
document.querySelector('.nav-menu').classList.toggle('is-active');
});
img {
max-width: 100%;
height: auto;
}
<picture>
<source media="(min-width: 1200px)" srcset="imagem-grande.jpg">
<source media="(min-width: 768px)" srcset="imagem-media.jpg">
<img src="imagem-pequena.jpg" alt="Descrição">
</picture>
.content-container {
display: flex;
flex-direction: column;
}
.main-content {
order: 2;
}
.sidebar {
order: 1;
}
@media (min-width: 768px) {
.content-container {
flex-direction: row;
}
.main-content {
order: 1;
flex: 3;
}
.sidebar {
order: 2;
flex: 1;
}
}
Este padrão permite que você reordene visualmente elementos sem alterar o HTML, ideal para casos onde o sidebar deve aparecer acima do conteúdo principal em mobile, mas ao lado em desktop.
Vamos aplicar os conceitos aprendidos criando um site de portfólio simples, mas totalmente responsivo. O site deve incluir:
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Meu Portfólio</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header class="header">
<div class="container">
<a href="#" class="logo">MeuPortfólio</a>
<button class="menu-toggle" aria-label="Menu">
<span></span>
<span></span>
<span></span>
</button>
<nav class="nav-menu">
<ul>
<li><a href="#">Home</a></li>
<li><a href="#projetos">Projetos</a></li>
<li><a href="#sobre">Sobre</a></li>
<li><a href="#contato">Contato</a></li>
</ul>
</nav>
</div>
</header>
<section class="hero">
<div class="container">
<div class="hero-content">
<h1>Olá, eu sou <span>Designer & Desenvolvedor</span></h1>
<p>Crio interfaces intuitivas e experiências digitais memoráveis</p>
<a href="#contato" class="btn">Entre em contato</a>
</div>
<div class="hero-image">
<img src="profile.jpg" alt="Minha foto" loading="lazy">
</div>
</div>
</section>
<section id="projetos" class="projetos">
<div class="container">
<h2>Meus Projetos</h2>
<div class="projetos-grid">
<div class="projeto-card">
<img src="projeto1.jpg" alt="Projeto 1">
<h3>Website Corporativo</h3>
<p>Design responsivo e desenvolvimento frontend</p>
</div>
<div class="projeto-card">
<img src="projeto2.jpg" alt="Projeto 2">
<h3>App Mobile</h3>
<p>Design de interface e prototipagem</p>
</div>
<div class="projeto-card">
<img src="projeto3.jpg" alt="Projeto 3">
<h3>E-commerce</h3>
<p>UX/UI e desenvolvimento responsivo</p>
</div>
<div class="projeto-card">
<img src="projeto4.jpg" alt="Projeto 4">
<h3>Blog Pessoal</h3>
<p>Design minimalista e SEO</p>
</div>
</div>
</div>
</section>
<section id="contato" class="contato">
<div class="container">
<h2>Entre em Contato</h2>
<div class="contato-container">
<div class="contato-info">
<p>Estou disponível para projetos freelance, oportunidades de trabalho ou apenas para trocar ideias.</p>
<div class="contato-dados">
<div><strong>Email:</strong> seuemail@exemplo.com</div>
<div><strong>Telefone:</strong> (00) 12345-6789</div>
</div>
</div>
<form class="contato-form">
<div class="form-group">
<label for="nome">Nome</label>
<input type="text" id="nome" required>
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" id="email" required>
</div>
<div class="form-group full-width">
<label for="mensagem">Mensagem</label>
<textarea id="mensagem" rows="5" required></textarea>
</div>
<button type="submit" class="btn">Enviar Mensagem</button>
</form>
</div>
</div>
</section>
<footer class="footer">
<div class="container">
<div class="redes-sociais">
<a href="#" aria-label="LinkedIn">LinkedIn</a>
<a href="#" aria-label="GitHub">GitHub</a>
<a href="#" aria-label="Behance">Behance</a>
<a href="#" aria-label="Instagram">Instagram</a>
</div>
<p>© 2025 Meu Portfólio. Todos os direitos reservados.</p>
</div>
</footer>
<script>
// Toggle menu mobile
document.querySelector('.menu-toggle').addEventListener('click', function() {
document.querySelector('.nav-menu').classList.toggle('is-active');
this.classList.toggle('is-active');
});
</script>
</body>
</html>
/* Base e Reset */
:root {
--color-primary: #5222d0;
--color-secondary: #ec615b;
--color-dark: #333;
--color-light: #f5f5f5;
--color-gray: #888;
--font-base: 16px;
--spacing-base: 1rem;
--border-radius: 4px;
--transition: all 0.3s ease;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {
font-size: var(--font-base);
scroll-behavior: smooth;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
line-height: 1.6;
color: var(--color-dark);
background: white;
}
img {
max-width: 100%;
height: auto;
display: block;
}
a {
text-decoration: none;
color: var(--color-primary);
transition: var(--transition);
}
ul {
list-style: none;
}
.container {
width: 100%;
max-width: 1200px;
margin: 0 auto;
padding: 0 var(--spacing-base);
}
.btn {
display: inline-block;
background: var(--color-primary);
color: white;
padding: 0.75rem 2rem;
border-radius: var(--border-radius);
font-weight: bold;
text-transform: uppercase;
letter-spacing: 1px;
font-size: 0.875rem;
transition: var(--transition);
border: none;
cursor: pointer;
}
.btn:hover {
background: var(--color-secondary);
transform: translateY(-3px);
box-shadow: 0 4px 10px rgba(0,0,0,0.15);
}
/* Header e Navegação */
.header {
position: sticky;
top: 0;
background: white;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
z-index: 100;
}
.header .container {
display: flex;
justify-content: space-between;
align-items: center;
height: 70px;
}
.logo {
font-weight: bold;
font-size: 1.5rem;
color: var(--color-dark);
}
.menu-toggle {
display: none;
background: none;
border: none;
cursor: pointer;
padding: 10px;
}
.menu-toggle span {
display: block;
width: 25px;
height: 3px;
background: var(--color-dark);
margin: 5px 0;
transition: var(--transition);
}
.nav-menu ul {
display: flex;
}
.nav-menu li {
margin-left: 2rem;
}
.nav-menu a {
color: var(--color-dark);
font-weight: 500;
}
.nav-menu a:hover {
color: var(--color-primary);
}
/* Hero Section */
.hero {
padding: 5rem 0;
background: var(--color-light);
}
.hero .container {
display: flex;
align-items: center;
gap: 3rem;
}
.hero-content {
flex: 1;
}
.hero-content h1 {
font-size: 2.5rem;
margin-bottom: 1rem;
line-height: 1.2;
}
.hero-content span {
color: var(--color-primary);
display: block;
font-size: 3rem;
}
.hero-content p {
font-size: 1.25rem;
color: var(--color-gray);
margin-bottom: 2rem;
}
.hero-image {
flex: 1;
text-align: center;
}
.hero-image img {
max-width: 80%;
border-radius: 50%;
border: 10px solid white;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
margin: 0 auto;
}
/* Projetos */
.projetos {
padding: 5rem 0;
}
.projetos h2 {
text-align: center;
margin-bottom: 3rem;
font-size: 2rem;
}
.projetos-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}
.projeto-card {
border-radius: var(--border-radius);
overflow: hidden;
box-shadow: 0 3px 10px rgba(0,0,0,0.1);
transition: var(--transition);
}
.projeto-card:hover {
transform: translateY(-10px);
box-shadow: 0 15px 30px rgba(0,0,0,0.15);
}
.projeto-card img {
height: 200px;
object-fit: cover;
width: 100%;
}
.projeto-card h3, .projeto-card p {
padding: 0 1.5rem;
}
.projeto-card h3 {
margin: 1.5rem 0 0.5rem;
}
.projeto-card p {
color: var(--color-gray);
margin-bottom: 1.5rem;
}
/* Contato */
.contato {
padding: 5rem 0;
background: var(--color-light);
}
.contato h2 {
text-align: center;
margin-bottom: 3rem;
font-size: 2rem;
}
.contato-container {
display: flex;
gap: 3rem;
}
.contato-info, .contato-form {
flex: 1;
}
.contato-dados {
margin-top: 1.5rem;
}
.contato-dados div {
margin-bottom: 0.5rem;
}
.form-group {
margin-bottom: 1.5rem;
}
.full-width {
grid-column: span 2;
}
label {
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
}
input, textarea {
width: 100%;
padding: 0.75rem;
border: 1px solid #ddd;
border-radius: var(--border-radius);
font-family: inherit;
font-size: 1rem;
}
input:focus, textarea:focus {
outline: none;
border-color: var(--color-primary);
box-shadow: 0 0 0 3px rgba(82, 34, 208, 0.1);
}
/* Footer */
.footer {
padding: 3rem 0;
background: var(--color-dark);
color: white;
text-align: center;
}
.redes-sociais {
display: flex;
justify-content: center;
gap: 2rem;
margin-bottom: 1.5rem;
}
.redes-sociais a {
color: white;
}
.redes-sociais a:hover {
color: var(--color-secondary);
}
.footer p {
font-size: 0.875rem;
opacity: 0.7;
}
/* Media Queries */
@media (max-width: 900px) {
.hero .container {
flex-direction: column;
text-align: center;
}
.hero-content {
order: 2;
}
.hero-image {
order: 1;
margin-bottom: 2rem;
}
.contato-container {
flex-direction: column;
}
}
@media (max-width: 768px) {
.menu-toggle {
display: block;
}
.nav-menu {
position: fixed;
top: 70px;
left: 0;
right: 0;
background: white;
height: 0;
overflow: hidden;
transition: var(--transition);
box-shadow: 0 5px 10px rgba(0,0,0,0.1);
}
.nav-menu.is-active {
height: auto;
padding: 1rem 0;
}
.nav-menu ul {
flex-direction: column;
padding: 0 var(--spacing-base);
}
.nav-menu li {
margin: 1rem 0;
margin-left: 0;
}
.menu-toggle.is-active span:nth-child(1) {
transform: rotate(45deg) translate(5px, 6px);
}
.menu-toggle.is-active span:nth-child(2) {
opacity: 0;
}
.menu-toggle.is-active span:nth-child(3) {
transform: rotate(-45deg) translate(5px, -6px);
}
.hero-content h1 {
font-size: 2rem;
}
.hero-content span {
font-size: 2.25rem;
}
}
@media (max-width: 480px) {
:root {
--font-base: 14px;
}
.hero {
padding: 3rem 0;
}
.projetos, .contato {
padding: 3rem 0;
}
.projetos-grid {
grid-template-columns: 1fr;
}
}
Guia completo sobre media queries com exemplos práticos e casos de uso.
Acessar →Curso gratuito do Google sobre os fundamentos do design responsivo.
Acessar →Ferramenta para visualizar seu site em diferentes tamanhos de dispositivos.
Acessar →Ferramenta simples que mostra as dimensões do seu navegador em tempo real.
Acessar →Resumo das principais técnicas e valores comuns para design responsivo.
Acessar →