web-dev-qa-db-fra.com

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

Comment espacer les requêtes média avec précision 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 pris en charge, à 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 régulier, mais sur une rétine?)


Je suis le plus curieux de savoir la réponse ici, compte tenu des spécifications.

75
Baumr

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

Cascade.

@media les règles sont transparentes pour la cascade, donc quand deux ou plusieurs @media les règles correspondent en même temps, le navigateur doit appliquer les styles dans toutes les règles qui correspondent et résoudre la cascade en conséquence.1

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

À exactement 20em de large, vos première et deuxième requêtes multimédias correspondront. Les navigateurs appliqueront des styles dans les deux @media règles et 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 gagne (en tenant compte des sélecteurs spécifiques, !important, etc). De même pour les deuxième et troisième requêtes mé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 fait exactement 20 m de large, ces deux requêtes multimédias renvoient true. Par la cascade, display: block remplace display: none et float: left s'appliquera à tout élément avec la classe .sidebar.

Vous pouvez le considérer comme l'application de règles comme si les requêtes des mé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 requêtes multimédias ou plus peut être trouvé dans cette autre réponse .

Soyez averti, cependant, que si vous avez des déclarations qui pas se chevauchent 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 ces dernières annulant complètement les premières ... ce qui nous amène à votre question précédente:

Comment espacer les requêtes média avec précision 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 le min- et max- les préfixes signifient "minimum inclus" et "maximum inclus"; ça signifie (min-width: 20em) et (max-width: 20em) correspondra à la fois à une fenêtre qui fait exactement 20 m 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 régulier, mais sur une rétine?)

Je ne suis pas tout à fait sûr de cela; toutes les valeurs de pixels en CSS sont des pixels logiques, et j'ai eu du mal à trouver un navigateur qui rapporterait une valeur de pixels fractionnaire pour une largeur de fenêtre. J'ai essayé d'expérimenter certains iframes mais je n'ai rien trouvé.

D'après mes expériences, il semblerait que Safari sur iOS arrondit toutes les valeurs de pixels fractionnaires pour garantir que l'un des max-width: 799px et min-width: 800px correspondra, même si la fenêtre d'affichage est en réalité de 799,5 pixels (ce qui correspond apparemment à la première).


1Bien que rien de tout cela ne soit explicitement indiqué dans le module Règles conditionnelles ou module Cascade (ce dernier étant actuellement prévu pour une réécriture), la cascade est implicite à prendre placer normalement, car la spécification dit simplement d'appliquer des styles dans n'importe quel @media règles qui correspondent au navigateur ou au média.

93
BoltClock

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 trouvé que ce n'était pas une bonne idée car cela ne fonctionne pas sur Chrome en ce moment ni sur mon bureau Ubuntu ni sur mon Android. Android (comme expliqué) ici: calc () ne fonctionne pas dans les requêtes média ) Mais, j'ai trouvé une meilleure façon ...

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

et bam!

calc() peut être utilisé pour contourner ce problème (min-width: 50em and max-width: calc(50em - 1px) 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é, ne pas utiliser l'unité em aiderait à empiler vos requêtes.

3
Milche Patern