Comment puis-je éviter le chevauchement des requêtes médias?
la cascade est ce qui rend CSS spécial et puissant. Mais dans le cas des requêtes des médias, le chevauchement peut semble problématique.
considérer les CSS suivants (en cours règles pour le chevauchement css media query ):
/* Standard - for all screens below 20em */
body { color: black; font-size: 1em; }
/* Query A - slightly wider, mobile viewport */
@media (min-width: 20em) and (max-width: 45em) {
body { color: red; } /* supposed to be unique for this width */
}
/* Query B - everything else */
@media (min-width: 45em) {
body { font-size: larger; } /* because viewport is bigger */
}
ainsi quand l'écran est exactement 45em de large, le chevauchement à 45em sera traité selon la cascade CSS standard:
- toutes
max-width: 45em
les définitions seront appliquées en premier, - et toutes
min-width: 45em
seront appliquées par la suite.
considérez ces deux conditions:
- tout le texte serait normalement
black
, mais requête a est unique et acolor: red
. - depuis Query B est pour les plus grands viewports, son texte a le CSS
font-size: larger
.
par conséquent, à une largeur d'exactement 45em, nous obtenions grand et texte rouge . Quelle serait la meilleure solution pour éviter cela?
je vois deux possibilités:
-
Re-déclarer le texte, d'avoir
color: black
dans "1519110920 de la Requête" B , mais alors, vous êtes à la gestion de deux déclarations si vous choisissez de changer lacolor
dans l'avenir. (Bien sûr, pas un tel problème avec cette seule ligne de code, mais imaginez qu'il y ait beaucoup d'autres déclarations et sélecteurs.) -
Évitez le chevauchement en utilisant des valeurs de pixels comme
max-width: 799px
etmin-width: 800px
, mais alors vous utilisez des pixels - je suppose qu'ils pourraient être 49.9375 em et 50em, respectivement. Et si la valeur par défaut n'est plus 16em et que quelque chose est arrondi? Et nous sommes toujours pas certain ce qui se passe à cet écart. (Un trou noir qui brise le continuum espace-temps?)
les deux ont leurs inconvénients... d'autres idées?
2 réponses
le seul moyen fiable de créer deux blocs mutuellement exclusifs @media
pour une requête donnée est d'utiliser not
pour la nier dans l'un des blocs. Malheureusement, cela signifie Répéter votre requête Média une fois pour chaque bloc @media
. Ainsi, au lieu de ceci par exemple:
@media (max-width: 49.9375em) {
body {
color: red;
}
}
@media (min-width: 50em) {
body {
font-size: larger;
}
}
vous auriez ceci:
/*
* Note: Media Queries 4 still requires 'not' to be followed by a
* media type (e.g. 'all' or 'screen') for reasons I cannot comprehend.
*/
@media not all and (min-width: 50em) {
body {
color: red;
}
}
@media (min-width: 50em) {
body {
font-size: larger;
}
}
C'est très efficace pour combler l'écart avec des caractéristiques de médias de gamme comme width
et height
car il transforme essentiellement cela en un soit-ou scénario. Mais, comme vos deux premières options, il n'est pas parfait: comme mentionné, vous devez répéter la même requête média deux fois, et ajouter not
à l'un d'eux. Il n'y a pas de construction if/else pour @media
comme décrit dans règles conditionnelles 3 .
bien que je mentionne dans ma réponse à votre question précédente:
D'après mes expériences, il semblerait que Safari sur iOS fait le tour de toutes les valeurs de pixels fractionnaires pour s'assurer que l'une ou l'autre de
max-width: 799px
etmin-width: 800px
correspond, même si le viewport est vraiment 799.5 px (ce qui correspond apparemment au premier).
il faut noter, encore, que j'ai remarqué quelques bizarreries quand il s'agit d'arrondir. Cela dit, je n'ai pas été en mesure de trouver un la valeur fractionnaire qui éviterait les deux les requêtes des médias et finir par ne pas recevoir les styles de l'un ou l'autre ensemble de règles (qui, soit dit en passant, est le pire qui puisse arriver, donc ne vous inquiétez pas de créer potentiellement une fissure espace-temps). Cela doit signifier les navigateurs - au moins, Safari comme je l'ai testé - faire un travail raisonnable de s'assurer qu'ils satisfont les requêtes des médias, même si vous avez des valeurs qui diffèrent (par exactement 1 pixel CSS).
quand il s'agit d'unités avec plus les lacunes qui peuvent être observées sur les navigateurs de bureau, bien que, comme ems, Il ya une marge d'erreur beaucoup plus grande. Par exemple, un commentaire suggère d'utiliser 49.99999 em au lieu de quelque chose de plus arbitraire que 49.9375 em, mais apparemment il y a une différence, au moins avec une taille de police par défaut de 16px.
j'ai simplifié votre code, changé les requêtes des Médias pour utiliser des valeurs décimales, et mis le code dans jsFiddle:
@media (max-width: 49.9375em) {
body {
color: red;
}
}
@media (min-width: 50em) {
body {
font-size: larger;
}
}
si vous redimensionnez le volet exactement 800 pixels (le texte sera mis à jour pour vous guider), vous finissez en fait avec des résultats différents selon que @media (max-width: 49.9375em)
est utilisé , ou @media (max-width: 49.99999em)
est utilisé (j'ai été surpris par cela aussi)...
dans tous les cas, vous avez raison: l'option 2 a ses inconvénients aussi. Je n'y suis pas particulièrement attaché, pour être honnête, parce que je ne voudrais pas casser ma tête sur l'appareil et les bizarreries de l'agent utilisateur qui sont hors de mon contrôle. Si vous êtes comme moi, je suppose qu'il serait préférable de faire les inconvénients de redeclaring vos règles au coût (?) d'être plus vigilant autour de votre code, car c'est au moins encore sous votre contrôle en tant qu'auteur.
Pour moi, la meilleure façon est de garder un écart de 0,01 em:
@media (min-width: 20em) and (max-width: 44.99em) {
body { color: red; } /* supposed to be unique for this width */
}
@media (min-width: 45em) {
body { font-size: larger; } /* because viewport is bigger */
}
je vous recommande de lire cet article pour les détails et la comparaison de la différentes solutions pour éviter le chevauchement de requête médias .
santé, Thomas.