Welche Regeln gelten für die Überlappung von CSS-Medienabfragen?

84

Wie platzieren wir Medienabfragen genau, um Überschneidungen zu vermeiden?

Wenn wir zum Beispiel den Code betrachten:

@media (max-width: 20em) {
    /* for narrow viewport */
}

@media (min-width: 20em) and (max-width: 45em) {
    /* slightly wider viewport */
}

@media (min-width: 45em) {
    /* everything else */
}

Was passiert in allen unterstützenden Browsern bei genau 20em und 45em?

Ich habe gesehen, wie Leute verwendet haben: Dinge wie 799px und dann 800px, aber was ist mit einer Bildschirmbreite von 799,5 px? (Offensichtlich nicht auf einem normalen Display, sondern auf einer Retina?)


Ich bin sehr gespannt auf die Antwort hier angesichts der Spezifikation.

Baumr
quelle
1
Ihr aktueller Fragentitel scheint nicht mit dem übereinzustimmen, was Sie fragen. Es scheint, als würde die erste Zeile Ihres
Frageninhalts
@ BoltClock, danke wie immer - ich habe sie umgeschaltet; aber wie haben Sie "Abstand zu Medienabfragen" interpretiert?
Baumr
1
@Baumr: Gute Frage - ich verstehe nicht ganz, was du damit meinst. Den Rest der Frage verstehe ich und schreibe eine Antwort.
BoltClock
1
Ich würde annehmen, wenn Sie eine Breite von genau 20em hätten, würden zuerst die max-width: 20emDefinitionen und dann auch die min-width: 20emDefinitionen angewendet .
Benutzer
1
@ Baumr, ich glaube, es kaskadiert genauso wie allgemeine CSS-Deklarationen. Da eine Breite von 20em beide Abfragen erfüllt, werden beide Abfragedefinitionen angewendet.
Benutzer

Antworten:

106

Welche Regeln gelten für die Überlappung von CSS-Medienabfragen?

Kaskade.

@mediaRegeln sind für die Kaskade transparent. Wenn also zwei oder mehr @mediaRegeln gleichzeitig übereinstimmen, sollte der Browser die Stile in allen übereinstimmenden Regeln anwenden und die Kaskade entsprechend auflösen. 1

Was passiert in allen unterstützenden Browsern bei genau 20em und 45em?

Bei einer Breite von genau 20 m stimmen sowohl Ihre erste als auch Ihre zweite Medienabfrage überein. Browser wenden Stile sowohl in @mediaRegeln als auch in Kaskaden entsprechend an. Wenn also widersprüchliche Regeln überschrieben werden müssen, gewinnt die zuletzt deklarierte (Berücksichtigung bestimmter Selektoren !importantusw.). Ebenso für die zweite und dritte Medienabfrage, wenn das Ansichtsfenster genau 45em breit ist.

In Anbetracht Ihres Beispielcodes wurden einige tatsächliche Stilregeln hinzugefügt:

@media (max-width: 20em) {
    .sidebar { display: none; }
}

@media (min-width: 20em) and (max-width: 45em) {
    .sidebar { display: block; float: left; }
}

Wenn das Browser-Ansichtsfenster genau 20 cm breit ist, geben diese beiden Medienabfragen true zurück. Durch die Kaskade werden alle Elemente der Klasse display: blocküberschrieben display: noneund float: leftangewendet .sidebar.

Sie können sich vorstellen, Regeln anzuwenden, als wären die Medienabfragen zunächst nicht da:

.sidebar { display: none; }
.sidebar { display: block; float: left; }

Ein weiteres Beispiel dafür, wie die Kaskade stattfindet, wenn ein Browser zwei oder mehr Medienabfragen entspricht, finden Sie in dieser anderen Antwort .

Seien Sie jedoch gewarnt, dass alle diese Regeln gelten , wenn Sie Erklärungen haben, die sich in beiden @mediaRegeln nicht überschneiden . Was hier passiert, ist eine Vereinigung der Erklärungen in beiden @mediaRegeln, nicht nur die letztere, die die erstere vollständig außer Kraft setzt ... was uns zu Ihrer früheren Frage bringt:

Wie platzieren wir Medienabfragen genau, um Überschneidungen zu vermeiden?

Wenn Sie Überschneidungen vermeiden möchten, müssen Sie lediglich Medienabfragen schreiben, die sich gegenseitig ausschließen.

Denken Sie daran, dass die Präfixe min-und max-"Minimum inklusive" und "Maximum inklusive" bedeuten. diese Mittel (min-width: 20em)und (max-width: 20em)wird sowohl ein Ansichtsfenster übereinstimmen , das ist genau das , 20em breit.

Es sieht so aus, als hätten Sie bereits ein Beispiel, das uns zu Ihrer letzten Frage bringt:

Ich habe gesehen, wie Leute verwendet haben: Dinge wie 799px und dann 800px, aber was ist mit einer Bildschirmbreite von 799,5 px? (Offensichtlich nicht auf einem normalen Display, sondern auf einer Retina?)

Das bin ich mir nicht ganz sicher; Alle Pixelwerte in CSS sind logische Pixel, und es ist mir schwer gefallen, einen Browser zu finden, der einen gebrochenen Pixelwert für eine Ansichtsfensterbreite meldet. Ich habe versucht, mit einigen Iframes zu experimentieren, konnte mir aber nichts einfallen lassen.

Aus meinen Experimenten geht hervor, dass Safari unter iOS alle gebrochenen Pixelwerte rundet, um sicherzustellen, dass einer von beiden übereinstimmt max-width: 799pxund min-width: 800pxübereinstimmt, auch wenn das Ansichtsfenster tatsächlich 799,5 Pixel groß ist (was anscheinend mit dem ersteren übereinstimmt).


1 Obwohl nichts davon explizit entweder in dem angegebenen Conditional Rules - Modul oder die Cascade - Modul (von denen die letztere derzeit für eine Rewrite geplant), wird die Kaskade implizierten Ort normalerweise zu nehmen, da einfach die Spezifikation sagt Stile in jedem anwenden und alle @mediaRegeln, die dem Browser oder den Medien entsprechen.

BoltClock
quelle
2
@Baumr: Kein Problem, obwohl ich noch nicht ganz fertig war - ich hatte Ihre Frage zu überlappenden Medienabfragen verpasst. Ich habe meine Antwort aktualisiert und nenne sie damit eine Nacht. Oh und nur zum Spaß: Medienabfragen sind eines meiner Lieblingsthemen in CSS, aber ich kann den Begriff RWD nicht ausstehen;)
BoltClock
BoltClock, es war vielleicht das erste Mal, dass ich "RWD" verwendet habe - Ihr kalter Empfang wurde bemerkt, haha! Gute Nacht, aber wenn Sie zurückkehren, lesen Sie das Update, das ich an der ursprünglichen Frage vorgenommen habe. Nun zu Ihrem Update ...
Baumr
BoltClock, sollte ich dieses Update herausnehmen und es zu einer eigenen Frage machen? Ich fühle, dass ich dies
verwickelt
@ Baumr: Ja, so ist es viel besser.
BoltClock
BoltClock: Ich habe es herausgenommen und in eine hoffentlich präzisere Frage gestellt: Wie vermeide ich eine Überlappung von Medienabfragen? - Wenn Sie Bearbeitungsvorschläge haben, um sie für andere Personen anwendbarer zu machen, teilen Sie sie bitte mit. PS Es lässt mich nicht @ dich in den Kommentaren.
Baumr
6

Ich habe versucht, wie hier empfohlen:

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

Ich fand jedoch, dass dies keine gute Idee war, da es derzeit weder auf meinem Ubuntu-Desktop noch auf meinem Android-Handy unter Chrome funktioniert. (wie hier erklärt: calc () funktioniert nicht in Medienabfragen ) Aber ich habe einen besseren Weg gefunden ...

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

und bam!

Pierre-Verthume Larivière
quelle
Dies sollte die akzeptierte Antwort sein. BoltClock lieferte die pedantische Antwort, aber diese Antwort ist die nützlichste!
John Henckel
2

calc()kann verwendet werden, um dies (min-width: 50em and max-width: calc(50em - 1px)zu umgehen, wird korrekt gestapelt), aber schlechte Browser-Unterstützung und ich würde es nicht empfehlen.

@media (min-width: 20em) and (max-width: calc(45em - 1px)) {
    /* slightly wider viewport */
}

Infos:

Einige andere erwähnten, emwenn Sie das Gerät nicht verwenden, können Sie Ihre Fragen besser stapeln.

Milche Patern
quelle
4
calc()ist nicht Teil der Medienabfragespezifikation und funktioniert nicht.
Jason T Featheringham