DEV Community

Cover image for A anatomia das Media Queries
Camilo Micheletto
Camilo Micheletto

Posted on

A anatomia das Media Queries

Geralmente a frase "pô usa media queries" vem como resposta pra pergunta "como posso fazer para deixar meu site mais resposivo?". Mas além de não ser a única at-rule (traduzindo literalmente, regra @), a @media tem muitas outras capacidades além de auxiliar na responsividade.

Nesse post iremos conhecer mais sobre a declaração @media e ver um panorama geral sobre suas capacidades.

 

O que são at-rules?

São basicamente declarações que dizem como o seu CSS deve se comportar, elas contém sempre um identificador (Ex: media, keyframes, supports) e podem ou não conter parâmetros e blocos. Elas são divididas em duas categorias, as normais e as aninhadas.
 

At-rules normais

São declarações que podem receber parâmetros mas não recebem blocos de código, servem pra configuração ou importação de documentos externos:

  • @charset
    Declaração utilizada para definir a faixa de caracteres Unicode que seu documento CSS vai utilizar (ex: UTF-8). O browser faz boa parte do trabalho, logo a sua declaração não é obrigatória, mas é interessante utilizá-la caso vá usar um grupo de caracteres diferenciado.

  • @import
    Essa declaração importa arquivos de uma URL para serem carregados juntamente com o seu CSS. Ela é composta basicamente da declaração @import seguida de um link, mas pode uma lista de media-queries como condições de carregamento:

/* Declaração básica, pode receber desde URL externas
até caminhos relativos */
@import "./main.css";

/* Carregando um arquivo de CSS apenas para dispositivos de mão
 com no máximo 400px de largura e que suportam display: flex */
@import url("mobile.css") supports(display: flex) handheld and (max-width: 400px);

/* Carregando CSS especificamente para o formato 
de paisagem
@import url('landscape.css') screen and (orientation:landscape);
Enter fullscreen mode Exit fullscreen mode

 

💡 !importante
O @import funciona de maneiras diferentes no CSS e no Sass/SCSS. Enquanto no CSS a importação carrega os documentos junto com o seu, no Sass o compilador coloca os arquivos importados dentro do mesmo documento. Atualmente o @import do Sass está sendo deixado de lado no lugar de @use e @forward que possuem maior controle de namespacing, permitem personalizar o carregamento das folhas de estilo usando a função with()

  • @namespace Declarando um namespace você consegue especificar dentro de qual contexto as suas declarações estão, seja HTML, SVG, XHTML ou XML por exemplo:
/* declaração <prefixo> url | string*/
@namespace svg "http://www.w3.org/2000/svg";

/* Utilizamos da seguinte forma: */

svg|a {
    /* um <a> dentro de um contexto SVG */
}   
Enter fullscreen mode Exit fullscreen mode

 

At-rules de grupos aninhados

São declarações que podem recebe trechos de código dentro delas que vão ser executados caso as condições se apliquem, as 3 mais comuns são @media, @keyframes e @supports.

 

@media

Primeira coisa sobre o @media é que a expressão media queries se refere às condições que passamos pra essa declaração, não a declaração em si. A parte da query é a expressão que vem depois de @media que vai sempre retornar true ou false. Quando a media query for verdadeira, as regras que estão dentro dela serão utilizadas no lugar das que já estão declaradas na raiz do documento.
Uma vez que um bloco de uma at-rule retorna verdadeiro, se ela tem um bloco de código se referenciando a um seletor específico, o seletor ja existente é substituído pelo de dentro do bloco

/* Exemplo retirado do MDN */

/* Na raiz do código */
article {
  padding: 0;
}

/* Se o documento tiver a largura de até 900px,
o seletor <article> vai receber o código da @media
abaixo, padding que já havia sido declarado será
sobreposto e a propriedade margin será acrescentada */
@media screen and (max-width: 900px) {
  article {
    padding: 1rem 3rem;
    margin-top: 5px;
  }
}

/* Aninhado com outra at-rule, o bloco dentro do
@media só será executado se a largura do documento
for de até 900px e se o navegador possuir suporte
para flexbox*/
@supports (display: flex) {
  @media screen and (max-width: 900px) {
    article {
      display: flex;
    }
  }
}

Enter fullscreen mode Exit fullscreen mode

Na declaração acima, a media query, ou seja, às condições para que o bloco de código .article seja executado são de que o tipo de mídia seja uma tela e que sua largura máxima seja de 900px. Se as condições forem verdadeiras, o elemento .article vai receber a propriedade padding: 1rem 3rem; que ira ser acrescentada a classe original ou substituirá caso essa classe já tenha um padding declarado.

Uma declaração @media pode ser formada por media types e media conditions, que juntos formam uma media query ou media condition:

Anatomia de um @media - Referência retirada da especificação oficial W3 (https://www.w3.org/TR/mediaqueries-4/#media), 24-02-2021

 

Media types

Media types se refere a que tipo de mídia o código se aplica, não especificamente dispositivos como celulares e TV, mas também mídia impressa e sintetizadores de voz, as media types são:

  • all
    O código é aplicável para todos as saídas de mídia, é o valor padrão.

  • screen
    O bloco de código é aplicável para telas.

  • print
    Código específico para impressão, muito útil para remover links, navegações e interações que não serão visíveis no documento impresso.

  • speech
    Configuração específica para sintetizadores de voz.

Usamos os media types da seguinte forma:

/* O media type 'all' é implícito se nenhum 
outro é declarado */

@media screen { /* ... */}
@media print{ /* ... */}
@media speech{ /* ... */}


/* Podemos utilizar a mesma regra para diferentes mídias
separando-os por vírgula */

@media screen, print { /* ... */ }


/* Podemos declarar no contexto de importação */

@import url(example.css) screen and (color), print and (color);

Enter fullscreen mode Exit fullscreen mode

Também podemos declará-las no elemento <link> ao carregar seu CSS no HTML:

<link 
  media="screen and (color),print and (color)"
  rel="stylesheet"
  href="example.css"
/>
Enter fullscreen mode Exit fullscreen mode

 

💡 !importante
É possível usar os operadores lógicos not | or | and para criar condicionais mais complexas para as suas declarações, eles funcionam tanto para os media types quanto pros media features:

/* Mídias de tela com largura máxima de 400px */
@media screen and (max-width: 400px) {
  /* ... */
}

/* Condição aplicada em dispositivos com tela que sejam
monocromáticos e possuam suporte para hover (um kindle talvez?)*/
@media screen and not ((color) or (hover)) {
  /* ... */
}
Enter fullscreen mode Exit fullscreen mode

 

Media features

Media features são características do user-agent (configurações padrão do navegador), ambiente e dispositivo. Todas essas características podem ser usadas como condições para definir a aplicabilidade do código.

/* Telas que tem no máximo 600px de largura e no mínimo
120ch de altura */
@media screen and (max-width: 600px) and (min-height: 120ch) {
  /* ... */
}

/* Telas cujo a largura é maior ou igual a 800px.
Declarações como width e height são computadas como valores
numéricos até que você declare uma unidade, suportando
assim os operadores lógicos =, >, <, >= e <= */
@media (width >= 600) {
  /* ... */
}
Enter fullscreen mode Exit fullscreen mode

Você pode acessar a lista gigante de media features que tem no MDN, mas vou elencar algumas bacanas, inclusive que saíram na especificação de nível 4 e 5 do CSS e que você pode conferir na íntegra no site da W3.

  • orientation
    Define regras para dispositivos em retrato (portrait) ou paisagem (landscape).

  • prefers-color-scheme
    Define regras de acordo com o tema configurado no navegador, aceita os valores light e dark, muito bom para definir o tema escuro do seu site. Ex:

:root {
  --background: #fff;
  --color: #1a1a1a;
}

@media (prefers-color-scheme: dark) {
/* Troca as cores das variáveis quando o tema for escuro */
  :root {
    --background: #1f212b;
    --color: #fff;
  }
}
Enter fullscreen mode Exit fullscreen mode

Para saber mais como utilizar essa feature query para fazer temas, leia esse post do Christopher Kirk-Nielsen.

  • prefers-reduced-motion Define configurações para usuários que tem problemas de leitura ou atenção com páginas muito animadas, esse post do WebDev explica muito bem o contexto dessa feature.
@media (prefers-reduced-motion) {
  .animation {
    /* Aqui você pode deixar a animação mais devagar ou
    completamente estática */
  }
}
Enter fullscreen mode Exit fullscreen mode
  • resolution Define a configuração de diferentes resoluções de tela, que podem afetar a visualização de fontes e imagens, aceita valores dpi(pontos por polegada) ou dpcm (pontos por centímetro):
@media (max-resolution: 300dpi) {
  p {
    background: yellow;
  }
}
Enter fullscreen mode Exit fullscreen mode

 

Quero saber mais

Para uma leitura ainda mais aprofundada a respeito do @media recomendo ir direto na especificação da W3 que apesar de densa tem detalhes muito legais que você não encontra em qualquer lugar. Recomendo também esse post da CSS Tricks que fala também sobre como acessar as @media via javascript (sim, é possível) e fala mais sobre nesting.


Muito obrigado por chegar até aqui! Tem uma dúvida ou mágoa? Faltou algo? Achou algo de errado? Comenta ai!

Discussion (0)