Comment espacer précisément les requêtes multimédias pour éviter les chevauchements?
Par exemple, si nous considérons le code:
@media (max-width: 20em) {
/* for narrow viewport */
}
@media (min-width: 20em) and (max-width: 45em) {
/* slightly wider viewport */
}
@media (min-width: 45em) {
/* everything else */
}
Que se passera-t-il, sur tous les navigateurs compatibles, à exactement 20em et 45em?
J'ai vu des gens utiliser: des choses comme 799px puis 800px, mais qu'en est-il d'une largeur d'écran de 799,5 px? (Évidemment pas sur un écran normal, mais sur un écran rétine?)
Je suis très curieux de connaître la réponse ici compte tenu des spécifications.
max-width: 20em
définitions, puis appliquerait également lesmin-width: 20em
définitions.Réponses:
Cascade.
@media
les règles sont transparentes pour la cascade, donc lorsque deux@media
règles ou plus correspondent en même temps, le navigateur doit appliquer les styles à toutes les règles qui correspondent et résoudre la cascade en conséquence. 1À exactement 20em de large, votre première et votre deuxième requête multimédia correspondent toutes les deux. Les navigateurs appliqueront les styles aux deux
@media
règles et en cascade en conséquence, donc s'il y a des règles en conflit qui doivent être remplacées, la dernière déclarée l'emporte (en tenant compte de sélecteurs spécifiques!important
, etc.). De même pour la deuxième et la troisième requête multimédia lorsque la fenêtre est exactement 45em de large.Compte tenu de votre exemple de code, avec quelques règles de style réelles ajoutées:
@media (max-width: 20em) { .sidebar { display: none; } } @media (min-width: 20em) and (max-width: 45em) { .sidebar { display: block; float: left; } }
Lorsque la fenêtre du navigateur mesure exactement 20em de large, ces deux requêtes multimédias renverront true. Par la cascade,
display: block
remplacedisplay: none
etfloat: left
s'appliquera à tout élément avec la classe.sidebar
.Vous pouvez considérer cela comme une application de règles comme si les requêtes multimédias n'étaient pas là pour commencer:
.sidebar { display: none; } .sidebar { display: block; float: left; }
Un autre exemple de la façon dont la cascade se déroule lorsqu'un navigateur correspond à deux ou plusieurs requêtes multimédias peut être trouvé dans cette autre réponse .
Sachez cependant que si vous avez des déclarations qui ne se chevauchent pas dans les deux
@media
règles, toutes ces règles s'appliqueront. Ce qui se passe ici est une union des déclarations dans les deux@media
règles, pas seulement la dernière annulant complètement la première ... ce qui nous amène à votre question précédente:Si vous souhaitez éviter les chevauchements, il vous suffit d'écrire des requêtes multimédias qui s'excluent mutuellement.
N'oubliez pas que les préfixes
min-
etmax-
signifient "minimum inclus" et "maximum inclus"; cela signifie(min-width: 20em)
et(max-width: 20em)
correspondra tous les deux à une fenêtre qui mesure exactement 20em de large.Il semble que vous ayez déjà un exemple, ce qui nous amène à votre dernière question:
Cela, je ne suis pas entièrement sûr; toutes les valeurs de pixel dans CSS sont des pixels logiques, et j'ai eu du mal à trouver un navigateur qui rapporterait une valeur de pixel fractionnaire pour une largeur de fenêtre. J'ai essayé d'expérimenter quelques iframes mais je n'ai rien pu trouver.
D'après mes expériences , il semblerait Safari sur iOS arrondit toutes les valeurs de pixels fractionnaires pour faire en sorte que l'une des
max-width: 799px
etmin-width: 800px
correspondra, même si la fenêtre est vraiment 799.5px (qui correspond apparemment l'ancien).1 Bien que rien de tout cela ne soit explicitement indiqué dans le module Règles conditionnelles ou dans le module Cascade (ce dernier étant actuellement prévu pour une réécriture), la cascade est implicite de se dérouler normalement, puisque la spécification dit simplement d'appliquer des styles dans et toutes les
@media
règles qui correspondent au navigateur ou au média.la source
J'ai essayé comme recommandé ici:
@media screen and (max-width: calc(48em - 1px)) { /*mobile styles*/ } @media screen and (min-width: 48em) { /*desktop styles*/ }
mais j'ai constaté que ce n'était pas une bonne idée car cela ne fonctionne pas sur Chrome pour le moment, ni sur mon bureau Ubuntu, ni sur mon téléphone Android. (comme expliqué ici: calc () ne fonctionne pas dans les requêtes multimédias ) Mais, j'ai trouvé un meilleur moyen ...
@media screen and (max-width: 47.9999em) { /*mobile styles*/ } @media screen and (min-width: 48em) { /*desktop styles*/ }
et bam!
la source
calc()
peut être utilisé pour contourner ce(min-width: 50em and max-width: calc(50em - 1px)
problème sera correctement empilé), mais le support du navigateur est médiocre et je ne le recommanderais pas.@media (min-width: 20em) and (max-width: calc(45em - 1px)) { /* slightly wider viewport */ }
Infos:
Certains autres ont mentionné que ne pas utiliser l'
em
unité aiderait à empiler vos requêtes.la source
calc()
ne fait pas partie de la spécification de requête multimédia et ne fonctionnera pas.