¿Cómo espaciamos las consultas de medios con precisión para evitar superposiciones?
Por ejemplo, si consideramos el 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 */
}
¿Qué pasará, en todos los navegadores compatibles, exactamente a 20em y 45em?
He visto a gente usar: cosas como 799px y luego 800px, pero ¿qué pasa con un ancho de pantalla de 799.5 px? (Obviamente no en una pantalla normal, sino en una retina)
Tengo más curiosidad por la respuesta aquí considerando la especificación.
max-width: 20em
definiciones, luego también aplicaría lasmin-width: 20em
definiciones.Respuestas:
Cascada.
@media
Las reglas son transparentes para la cascada, por lo que cuando dos o más@media
reglas coinciden al mismo tiempo, el navegador debe aplicar los estilos en todas las reglas que coincidan y resolver la cascada en consecuencia. 1Con exactamente 20 em de ancho, su primera y segunda consulta de medios coincidirán. Los navegadores aplicarán estilos en ambas
@media
reglas y en cascada en consecuencia, por lo que si hay reglas en conflicto que deben anularse, gana la última declarada (teniendo en cuenta selectores específicos!important
, etc.). Lo mismo ocurre con la segunda y tercera consulta de medios cuando la ventana gráfica tiene exactamente 45 em de ancho.Teniendo en cuenta su código de ejemplo, con algunas reglas de estilo reales agregadas:
@media (max-width: 20em) { .sidebar { display: none; } } @media (min-width: 20em) and (max-width: 45em) { .sidebar { display: block; float: left; } }
Cuando la ventana del navegador tiene exactamente 20 em de ancho, ambas consultas de medios volverán verdaderas. Por la cascada,
display: block
anuladisplay: none
yfloat: left
se aplicará a cualquier elemento de la clase.sidebar
.Puede pensar en ello como una aplicación de reglas como si las consultas de medios no estuvieran allí para empezar:
.sidebar { display: none; } .sidebar { display: block; float: left; }
Otro ejemplo de cómo ocurre la cascada cuando un navegador coincide con dos o más consultas de medios se puede encontrar en esta otra respuesta .
Sin embargo, tenga en cuenta que si tiene declaraciones que no se superponen en ambas
@media
reglas, se aplicarán todas esas reglas. Lo que sucede aquí es una unión de las declaraciones en ambas@media
reglas, no solo la última anula por completo la primera ... lo que nos lleva a su pregunta anterior:Si desea evitar la superposición, simplemente debe escribir consultas de medios que sean mutuamente excluyentes.
Recuerde que los prefijos
min-
ymax-
significan "mínimo inclusivo" y "máximo inclusivo"; este medio(min-width: 20em)
y(max-width: 20em)
coincidirá tanto una ventana que es exactamente 20em amplia.Parece que ya tienes un ejemplo, lo que nos lleva a tu última pregunta:
De esto no estoy del todo seguro; todos los valores de píxeles en CSS son píxeles lógicos, y me ha costado mucho encontrar un navegador que informe un valor de píxel fraccionario para un ancho de ventana gráfica. He intentado experimentar con algunos iframes pero no he podido encontrar nada.
Según mis experimentos, parecería que Safari en iOS redondea todos los valores de píxeles fraccionarios para garantizar que cualquiera de
max-width: 799px
ymin-width: 800px
coincida, incluso si la ventana gráfica es realmente 799.5px (que aparentemente coincide con el primero).1 Aunque nada de esto se indica explícitamente ni en el módulo de Reglas condicionales ni en el módulo Cascade (el último de los cuales está actualmente programado para una reescritura), se da a entender que la cascada tiene lugar normalmente, ya que la especificación simplemente dice que se apliquen estilos en cualquier y todas las
@media
reglas que coincidan con el navegador o el medio.fuente
He intentado como se recomienda aquí:
@media screen and (max-width: calc(48em - 1px)) { /*mobile styles*/ } @media screen and (min-width: 48em) { /*desktop styles*/ }
pero descubrí que esta no era una buena idea porque no funciona en Chrome en este momento ni en mi escritorio Ubuntu ni en mi teléfono Android. (como se explica aquí: calc () no funciona dentro de las consultas de medios ) Pero encontré una mejor manera ...
@media screen and (max-width: 47.9999em) { /*mobile styles*/ } @media screen and (min-width: 48em) { /*desktop styles*/ }
y bam!
fuente
calc()
se puede utilizar para solucionar esto(min-width: 50em and max-width: calc(50em - 1px)
se apilará correctamente), pero la compatibilidad con el navegador es deficiente y no lo recomendaría.@media (min-width: 20em) and (max-width: calc(45em - 1px)) { /* slightly wider viewport */ }
Infos:
Algunos otros mencionaron que no usar la
em
unidad ayudaría en el apilamiento de sus consultas.fuente
calc()
no forma parte de la especificación de consulta de medios y no funcionará.