Uma media query CSS aplica um bloco de estilos só quando o aparelho ou o navegador atende a uma condição, como uma largura mínima de viewport, orientação paisagem ou esquema de cores escuro. @media (min-width: 48rem) { ... } significa “use estas regras quando o viewport tiver pelo menos 48rem de largura”. As media queries são a parte do CSS que permite a uma mesma página mudar o layout entre celular, tablet e desktop.
Sintaxe básica
@media (min-width: 768px) {
.sidebar { display: block; }
}
Uma media query tem três partes opcionais:
- um tipo de mídia:
screen,printouall(padrão); - um ou mais recursos de mídia entre parênteses, como
(min-width: 768px)ou(orientation: landscape); - operadores lógicos que os combinam:
and,,(ou) enot.
@media screen and (min-width: 768px) and (orientation: landscape) { ... }
@media (max-width: 480px), (orientation: portrait) { ... }
@media not print { ... }
Também dá para aplicar uma media query a uma folha de estilo inteira: <link rel="stylesheet" href="print.css" media="print">.
min-width ou max-width
min-width significa “desta largura ou mais”; max-width, “desta largura ou menos”. A direção escolhida define como você escreve o resto do CSS.
- Mobile first (recomendado): os estilos base miram o celular, e queries com
min-widthacrescentam o layout das telas maiores. Veja design mobile first. - Desktop first: os estilos base miram o desktop, e queries com
max-widthdesfazem coisas nas telas menores.
/* Mobile first */
.nav { flex-direction: column; }
@media (min-width: 48rem) {
.nav { flex-direction: row; }
}
Misturar as duas direções no mesmo projeto costuma criar sobreposições e buracos. Escolha uma e use a outra só para pequenas exceções.
A sintaxe moderna de intervalos
O Media Queries Level 4 traz operadores de comparação, mais fáceis de ler e que evitam erros de um pixel:
@media (width >= 48rem) { ... }
@media (40rem <= width < 64rem) { ... }
A sintaxe de intervalos é suportada em todos os principais navegadores atuais (Chrome e Edge desde a versão 104, Firefox desde a 63, Safari desde a 16.4). Se você precisa dar suporte a versões antigas do Safari, continue usando min-width e max-width ou deixe uma ferramenta de build fazer a conversão.
Repare que (width < 768px) e (max-width: 767px) não são iguais: a primeira também vale para 767,5 px, o que pode acontecer em telas com densidade de pixels fracionada.
Media queries para celular: exemplos comuns
Empilhar colunas em telas pequenas:
.grid { display: grid; gap: 1rem; }
@media (min-width: 40rem) {
.grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 64rem) {
.grid { grid-template-columns: repeat(4, 1fr); }
}
Espaçamento menor no celular:
.section { padding: 2rem 1rem; }
@media (min-width: 64rem) {
.section { padding: 6rem 2rem; }
}
Celular em paisagem, com pouca altura:
@media (orientation: landscape) and (max-height: 30rem) {
.site-header { position: static; }
}
Este último é muito esquecido. Um header fixo que fica bom em retrato pode ocupar um terço da tela em paisagem.
Quais larguras usar é outra questão, tratada em breakpoints responsivos.
Recursos de mídia além da largura
| Recurso | Exemplo | Para que serve |
|---|---|---|
orientation |
(orientation: landscape) |
Mudar o layout quando o celular ou tablet gira |
hover |
(hover: hover) |
Efeitos de hover só em aparelhos que têm hover |
pointer |
(pointer: coarse) |
Áreas de toque maiores em telas sensíveis ao toque |
prefers-color-scheme |
(prefers-color-scheme: dark) |
Tema escuro |
prefers-reduced-motion |
(prefers-reduced-motion: reduce) |
Desligar animações |
resolution |
(min-resolution: 2dppx) |
Imagens de alta densidade em fundos CSS |
display-mode |
(display-mode: standalone) |
Estilizar um web app instalado |
Os recursos hover e pointer importam mais do que parece. Um notebook com tela de toque ou um tablet com layout de largura desktop continua sem hover, então proteja menus que só abrem no hover com @media (hover: hover).
Use rem ou em nos breakpoints
Media queries em rem ou em seguem o tamanho de fonte que o usuário definiu no navegador. Se alguém aumenta o texto padrão de 16 px para 24 px, um breakpoint de 48rem passa de 768 px para 1152 px, e o layout muda para uma versão mais espaçosa quando o texto cresce. Breakpoints em pixels ignoram essa configuração. Dentro das media queries, rem e em se referem ao tamanho de fonte inicial do navegador, não ao tamanho do html que você definiu no CSS.
Media queries ou container queries
Media queries respondem ao viewport. Container queries respondem ao tamanho do container de um elemento:
.card-wrap { container-type: inline-size; }
@container (min-width: 30rem) {
.card { display: flex; }
}
Use media queries para o layout da página (colunas, navegação) e container queries para componentes que aparecem em lugares com larguras diferentes.
Erros comuns
- Falta da meta tag viewport. Sem ela, o celular informa um viewport de uns 980 px e as suas media queries mobile nunca disparam. Veja a meta tag viewport explicada.
- Intervalos sobrepostos, como
max-width: 768pxemin-width: 768px, que valem os dois em exatamente 768 px. - Escrever a media query antes da regra base. Com a mesma especificidade, a regra posterior vence, então a query precisa vir depois da regra que ela sobrescreve.
- Testar só redimensionando a janela. Navegadores de desktop não encolhem até a largura da maioria dos celulares. Use o modo dispositivo ou o Mobile View Extension, que define o viewport e o user agent reais, e veja como testar a responsividade de um site.
Perguntas frequentes
Qual é a media query para celular?
Não existe uma única query para celular. No CSS mobile first, o celular é o padrão, sem query, e você acrescenta @media (min-width: 40rem) ou algo parecido para telas maiores. Para mirar só telas pequenas, use @media (max-width: 39.99rem) ou (width < 40rem).
Media queries devem usar px, em ou rem?
rem ou em é melhor para acessibilidade, porque os breakpoints acompanham o tamanho de fonte do usuário. px funciona, mas ignora essa configuração.
Onde colocar as media queries no CSS?
Ao lado do componente que elas alteram ou agrupadas no fim do arquivo. Ao lado do componente é mais fácil de manter, e de qualquer forma elas precisam vir depois das regras base.