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.
max-width: 20em
definições e, em seguida, também aplicaria asmin-width: 20em
definições.Respostas:
Cascata.
@media
as regras são transparentes para a cascata, portanto, quando duas ou mais@media
regras correspondem ao mesmo tempo, o navegador deve aplicar os estilos em todas as regras que correspondem e resolver a cascata de acordo. 1Com exatamente 20em de largura, sua primeira e segunda consulta de mídia serão correspondentes. Os navegadores irão aplicar estilos em ambas as
@media
regras 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: block
substituidisplay: none
efloat: left
será 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
@media
regras, todas essas regras serão aplicadas. O que acontece aqui é uma união das declarações em ambas as@media
regras, não apenas a última anulando completamente a primeira ... o que nos leva à sua pergunta anterior: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-
emax-
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:
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: 799px
emin-width: 800px
corresponderá, 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
@media
regras que correspondem ao navegador ou mídia.fonte
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!
fonte
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
em
unidade ajudaria no empilhamento de suas consultas.fonte
calc()
não faz parte das especificações da consulta de mídia e não funcionará.