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);
💡 !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çãowith()
-
@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 */
}
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.
/* 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;
}
}
}
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:
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);
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"
/>
💡 !importante
É possível usar os operadores lógicosnot | 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)) {
/* ... */
}
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) {
/* ... */
}
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 valoreslight
edark
, 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;
}
}
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 */
}
}
-
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;
}
}
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!
Top comments (0)