Quais são as regras para sobreposição de consulta de mídia CSS?

88

Como espaçamos as consultas de mídia com precisão para evitar sobreposições?

Por exemplo, se considerarmos o código:

@media (max-width: 20em) {
    /* for narrow viewport */
}

@media (min-width: 20em) and (max-width: 45em) {
    /* slightly wider viewport */
}

@media (min-width: 45em) {
    /* everything else */
}

O que acontecerá, em todos os navegadores compatíveis, exatamente em 20em e 45em?

Já vi pessoas usarem: coisas como 799 px e 800 px, mas e uma largura de tela de 799,5 px? (Obviamente, não em uma tela normal, mas em uma retina?)


Estou mais curioso para saber a resposta aqui, considerando as especificações.

Baumr
fonte
1
O título da sua pergunta atual não parece corresponder ao que você está perguntando. Parece que a primeira linha do conteúdo da sua pergunta caberia melhor como o título :)
BoltClock
@BoltClock, obrigado como sempre - troquei-os; mas como você interpretou "espaçamento das consultas da mídia"?
Baumr
1
@Baumr: Boa pergunta - não entendo muito bem o que você quer dizer com isso, na verdade. O resto da pergunta eu entendo e estou escrevendo uma resposta.
BoltClock
1
Eu presumiria que se você tivesse uma largura de exatamente 20em, então primeiro aplicaria as max-width: 20emdefinições e, em seguida, também aplicaria as min-width: 20emdefinições.
usuário
1
@Baumr, acredito que esteja em cascata da mesma forma que as declarações gerais de CSS. Como uma largura de 20em satisfaz ambas as consultas, ambas as definições de consulta serão aplicadas.
usuário

Respostas:

108

Quais são as regras para sobreposição de consulta de mídia CSS?

Cascata.

@mediaas regras são transparentes para a cascata, portanto, quando duas ou mais @mediaregras correspondem ao mesmo tempo, o navegador deve aplicar os estilos em todas as regras que correspondem e resolver a cascata de acordo. 1

O que acontecerá, em todos os navegadores compatíveis, exatamente em 20em e 45em?

Com exatamente 20em de largura, sua primeira e segunda consulta de mídia serão correspondentes. Os navegadores irão aplicar estilos em ambas as @mediaregras e em cascata de acordo, portanto, se houver alguma regra conflitante que precise ser substituída, a última declarada vence (levando em conta seletores específicos !important, etc.). O mesmo ocorre com a segunda e a terceira consulta de mídia quando a janela de visualização tem exatamente 45em de largura.

Considerando seu código de exemplo, com algumas regras de estilo reais adicionadas:

@media (max-width: 20em) {
    .sidebar { display: none; }
}

@media (min-width: 20em) and (max-width: 45em) {
    .sidebar { display: block; float: left; }
}

Quando a janela de visualização do navegador tiver exatamente 20em de largura, ambas as consultas de mídia retornarão verdadeiras. Pela cascata, display: blocksubstitui display: nonee float: leftserá aplicado a qualquer elemento da classe .sidebar.

Você pode pensar nisso como aplicar regras como se as consultas de mídia não estivessem lá para começar:

.sidebar { display: none; }
.sidebar { display: block; float: left; }

Outro exemplo de como a cascata ocorre quando um navegador corresponde a duas ou mais consultas de mídia pode ser encontrado nesta outra resposta .

Esteja avisado, entretanto, que se você tiver declarações que não se sobrepõem em ambas as @mediaregras, todas essas regras serão aplicadas. O que acontece aqui é uma união das declarações em ambas as @mediaregras, não apenas a última anulando completamente a primeira ... o que nos leva à sua pergunta anterior:

Como espaçamos as consultas de mídia com precisão para evitar sobreposições?

Se você deseja evitar a sobreposição, simplesmente precisa escrever consultas de mídia que sejam mutuamente exclusivas.

Lembre-se de que os prefixos min-e max-significam "mínimo inclusivo" e "máximo inclusive"; isso significa (min-width: 20em)e (max-width: 20em)corresponderá a uma janela de visualização com exatamente 20em de largura.

Parece que você já tem um exemplo, o que nos leva à sua última pergunta:

Já vi pessoas usarem: coisas como 799 px e 800 px, mas e uma largura de tela de 799,5 px? (Obviamente, não em uma tela normal, mas em uma retina?)

Não estou totalmente certo disso; todos os valores de pixel em CSS são pixels lógicos, e tenho sido muito pressionado para encontrar um navegador que relataria um valor de pixel fracionário para a largura de uma janela de visualização. Eu tentei experimentar alguns iframes, mas não consegui encontrar nada.

Pelos meus experimentos, parece que o Safari no iOS arredonda todos os valores de pixel fracionário para garantir que qualquer um dos max-width: 799pxe min-width: 800pxcorresponderá, mesmo se a janela de visualização for realmente 799,5 px (o que aparentemente corresponde ao anterior).


1 Embora nada disso seja explicitamente declarado no módulo Regras condicionais ou no módulo Cascade (o último dos quais está atualmente programado para uma reescrita), a cascata está implícita para ocorrer normalmente, uma vez que a especificação simplesmente diz para aplicar estilos em qualquer e todas as @mediaregras que correspondem ao navegador ou mídia.

BoltClock
fonte
2
@Baumr: Sem problemas, embora eu ainda não tenha acabado - não entendi sua pergunta sobre a sobreposição de consultas à mídia. Atualizei minha resposta e com isso estou encerrando a noite. Ah, e só por diversão: consultas de mídia são um dos meus tópicos favoritos em CSS, mas não suporto o termo RWD;)
BoltClock
BoltClock, pode ter sido a primeira vez que usei "RWD" na verdade - sua recepção fria foi notada, haha! Boa noite, mas quando voltar, confira a atualização que fiz na pergunta original. Agora, para dar uma olhada em sua atualização ...
Baumr
BoltClock, devo tirar essa atualização e transformá-la em sua própria pergunta? Sinto que estou tornando isso complicado
Baumr
@Baumr: Sim, é muito melhor assim.
BoltClock
BoltClock: Eu o peguei e coloquei em uma pergunta, espero, mais concisa: Como evitar a sobreposição de consultas de mídia? - se você tiver alguma sugestão de edição para torná-lo mais aplicável a outras pessoas, compartilhe. PS Não está me deixando @ você nos comentários.
Baumr
6

Eu tentei conforme recomendado aqui:

@media screen and (max-width: calc(48em - 1px)) {
    /*mobile styles*/
}
@media screen and (min-width: 48em) {
    /*desktop styles*/
}

mas descobri que isso não era uma boa ideia porque ele não funciona no Chrome agora, nem na área de trabalho do Ubuntu nem no meu telefone Android. (conforme explicado aqui: calc () não funciona em consultas de mídia ) Mas, eu encontrei uma maneira melhor ...

@media screen and (max-width: 47.9999em) {
    /*mobile styles*/
}
@media screen and (min-width: 48em) {
    /*desktop styles*/
}

e bam!

Pierre-Verthume Larivière
fonte
Esta deve ser a resposta aceita. BoltClock forneceu a resposta pedante, mas esta resposta é a mais útil!
John Henckel
2

calc()pode ser usado para contornar isso (min-width: 50em and max-width: calc(50em - 1px)será empilhado corretamente), mas o suporte do navegador é ruim e eu não recomendaria isso.

@media (min-width: 20em) and (max-width: calc(45em - 1px)) {
    /* slightly wider viewport */
}

Infos:

Alguns outros mencionaram, não usar a emunidade ajudaria no empilhamento de suas consultas.

Milche Patern
fonte
4
calc()não faz parte das especificações da consulta de mídia e não funcionará.
Jason T Featheringham