Range Syntax em Media Queries
Media queries são a espinha dorsal do web design responsivo. São elas que controlam como um layout deve se ajustar conforme o tamanho da viewport. O problema é que a sintaxe com min-width e max-width pode confundir e, em alguns casos, gerar bugs de layout que consomem tempo para serem identificados.
Felizmente, agora temos uma alternativa mais legível e mais fácil de usar e depurar: a Range Syntax (ou Sintaxe de Intervalos).
O problema com media queries
Imagine um padrão clássico de navegação: no mobile, apenas o logo e o botão de menu (toggle) aparecem; em telas maiores, a navegação fica visível e o toggle é escondido.
A seguir, as media queries usadas para isso:
/* Esconde a navegação em tamanhos pequenos */.nav { @media (max-width: 300px) { display: none; }}
/* Esconde o toggle em tamanhos grandes */.toggle { @media (min-width: 300px) { display: none; }}O problema acontece quando as duas media queries se encontram no mesmo valor de breakpoint (300px): ambos elementos serão escondidos ao mesmo tempo.
Vale lembrar:
max-widthequivale a<=min-widthequivale a>=
Ao chegar exatamente em 300px, tanto o menu quanto o botão somem ao mesmo tempo.
Essa é a confusão que aparece ao usar min-width e max-width apontando para o mesmo valor de breakpoint.
Quando o foco está só no que se está construindo, é fácil deixar esse detalhe passar e acabar 45 minutos debugando…
A frustração é real. Para resolver, é preciso usar dois valores diferentes:
max-width: 299px: significa menor ou igual a 299pxmin-width: 300px: significa maior ou igual a 300px
/* Esconde a navegação em tamanhos pequenos */.nav { @media (max-width: 299px) { display: none; }}
/* Esconde o toggle em tamanhos grandes */.toggle { @media (min-width: 300px) { display: none; }}Assim, quando a viewport chega em 300px, a navegação aparece e o toggle some. Sem sobreposição.
Para um caso isolado como esse, a solução funciona. Mas quando o projeto tem vários breakpoints, manter esses ajustes de 1px começa a ficar trabalhoso.
Conheça as media queries ranges
As range media queries (ou intevalos de media queries) resolvem esse problema sem precisar deslocar breakpoints manualmente.
Basta usar operadores de comparação para escrever a mesma regra de forma mais legível:
/* Menor ou igual a 300px */.nav { @media (width <= 300px) { display: none; }}
/* Maior que 300px */.toggle { @media (width > 300px) { display: none; }}Isso fica muito mais claro porque é possível ler os operadores e entender a lógica diretamente, sem ter que “decifrar” o que min- ou max- querem dizer.
Essa sintaxe faz parte do módulo Media Queries Level 4.
Por que usar range media queries?
Legibilidade
São mais fáceis de ler e entender. Ao bater o olho no CSS, dá para perceber o que a regra significa sem precisar adivinhar. E isso facilita muito a conferência e debug.
Bem suportadas
O suporte dos principais navegadores tem status de Amplamente Disponível desde março de 2023.
Facilita os intervalos
Quando o objetivo é limitar parte do design entre dois breakpoints, a sintaxe fica bem mais enxuta:
/* Antes */.section { @media (min-width: 300px) and (max-width: 500px) { /* estilos para o card */ }}
/* Depois */.section { @media (300px <= width <= 500px) { /* estilos para o card */ }}A leitura segue exatamente o sentido da regra: “largura entre 300px e 500px”.
Não é só para media queries
A sintaxe de intervalos também serve para container queries.
Basta trocar @media por @container:
h1 { @container (width >= 300px) { color: #fff; background-color: var(--brand-1); }
@container (width >= 500px) { background-color: hsl(from var(--brand-1) calc(h + 100) s l); }}Veja o resultado:
Conclusão
As range media queries são mais claras, mais fáceis de ler e de debugar e têm suporte sólido entre os principais navegadores.
O suporte é garantido e as vantagens que elas oferecem são muitas. Certamente, vale a pena começar a usá-las a partir do próximo projeto.