Quelles sont les règles de chevauchement des requêtes multimédias CSS?

89

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.

Baumr
la source
1
Le titre de votre question actuelle ne semble pas correspondre à ce que vous demandez. Il semble que la première ligne du contenu de votre question conviendrait mieux au titre :)
BoltClock
@BoltClock, merci comme toujours - je les ai inversés; mais comment avez-vous interprété «l'espacement des requêtes médiatiques»?
Baumr
1
@Baumr: Bonne question - je ne comprends pas tout à fait ce que vous entendez par là, en fait. Le reste de la question je comprends et j'écris une réponse.
BoltClock
1
Je suppose que si vous aviez une largeur d'exactement 20em, il appliquerait d'abord les max-width: 20emdéfinitions, puis appliquerait également les min-width: 20emdéfinitions.
utilisateur
1
@Baumr, je crois qu'il s'agit simplement de la même cascade que les déclarations CSS générales. Puisqu'une largeur de 20em satisfait les deux requêtes, les deux définitions de requête vont être appliquées.
utilisateur

Réponses:

109

Quelles sont les règles de chevauchement des requêtes multimédias CSS?

Cascade.

@mediales règles sont transparentes pour la cascade, donc lorsque deux @mediarè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

Que se passera-t-il, sur tous les navigateurs compatibles, à exactement 20em et 45em?

À 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 @mediarè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: blockremplace display: noneet float: lefts'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 @mediarègles, toutes ces règles s'appliqueront. Ce qui se passe ici est une union des déclarations dans les deux @mediarègles, pas seulement la dernière annulant complètement la première ... ce qui nous amène à votre question précédente:

Comment espacer précisément les requêtes multimédias pour éviter les chevauchements?

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-et max-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:

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?)

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: 799pxet min-width: 800pxcorrespondra, 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 @mediarègles qui correspondent au navigateur ou au média.

BoltClock
la source
2
@Baumr: Pas de problème, même si je n'avais pas encore tout à fait fini - j'avais manqué votre question sur les requêtes médias qui se chevauchent. J'ai mis à jour ma réponse et j'appelle ça une nuit. Oh et juste pour les coups de pied: les requêtes multimédias sont l'un de mes sujets préférés en CSS, mais je ne supporte pas le terme RWD;)
BoltClock
BoltClock, c'était peut-être la première fois que j'utilisais "RWD" en fait - votre accueil froid a été noté, haha! Bonne nuit, mais à votre retour, consultez la mise à jour que j'ai apportée à la question d'origine. Maintenant, pour regarder votre mise à jour ...
Baumr
BoltClock, devrais-je supprimer cette mise à jour et en faire sa propre question? Je sens que je fais cela alambiqué
Baumr
@Baumr: Ouais, c'est beaucoup mieux comme ça.
BoltClock
BoltClock: Je l'ai sorti et je l'ai mis dans une question, espérons-le, plus concise: Comment éviter le chevauchement des requêtes multimédias? - Si vous avez des suggestions de modification pour le rendre plus applicable à d'autres personnes, veuillez les partager. PS Il ne me laisse pas @ vous dans les commentaires.
Baumr
6

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!

Pierre-Verthume Larivière
la source
Cela devrait être la réponse acceptée. BoltClock a fourni la réponse pédante, mais cette réponse est la plus utile!
John Henckel
2

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' emunité aiderait à empiler vos requêtes.

Milche Patern
la source
4
calc()ne fait pas partie de la spécification de requête multimédia et ne fonctionnera pas.
Jason T Featheringham