web-dev-qa-db-ger.com

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

Wie verteilen wir Medienabfragen genau, um Überlappungen 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ützten Browsern bei genau 20 und 45?

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


Ich bin sehr gespannt auf die Antwort hier, wenn man die Spezifikation berücksichtigt.

75
Baumr

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

Kaskade.

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

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

Bei einer Breite von genau 20 Metern stimmen die erste und die zweite Medienabfrage überein. Browser wenden Stile in beiden @media - Regeln an und kaskadieren entsprechend. Wenn also widersprüchliche Regeln überschrieben werden müssen, gewinnt die zuletzt deklarierte (unter Berücksichtigung bestimmter Selektoren, !important Usw.) ). Ebenso für die zweite und dritte Medienabfrage, wenn das Ansichtsfenster genau 45em breit ist.

In Anbetracht Ihres Beispielcodes wurden einige aktuelle 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-fach ist, werden beide Medienabfragen als true zurückgegeben. Durch die Kaskade überschreibt display: blockdisplay: none Und float: left Wird auf jedes Element mit der Klasse .sidebar Angewendet.

Sie können sich vorstellen, dass Regeln angewendet werden, als ob die Medienabfragen nicht vorhanden wären:

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

Ein weiteres Beispiel dafür, wie die Kaskade stattfindet, wenn ein Browser zwei oder mehr Medienabfragen erfüllt, finden Sie in diese andere Antwort .

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

Wie verteilen wir Medienabfragen genau, um Überlappungen 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. Dies bedeutet, dass sowohl (min-width: 20em) als auch (max-width: 20em) mit einem Ansichtsfenster übereinstimmen, das genau 20em breit ist.

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

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

Das bin ich mir nicht ganz sicher; Alle Pixelwerte in CSS sind logische Pixel, und ich habe Mühe gehabt, einen Browser zu finden, der einen gebrochenen Pixelwert für eine Ansichtsfensterbreite angibt. Ich habe versucht, mit einigen iframes zu experimentieren, konnte aber nichts finden.

Aus meinen Experimenten geht hervor, dass Safari unter iOS alle gebrochenen Pixelwerte rundet, um sicherzustellen, dass entweder max-width: 799px Oder min-width: 800px Übereinstimmen, auch wenn das Ansichtsfenster wirklich 799,5 Pixel groß ist (was anscheinend mit dem ersteren übereinstimmt ).


1Obwohl nichts davon explizit in den Modulen Bedingte Regeln oder Kaskadenmodul angegeben ist (letzteres ist derzeit für ein Umschreiben vorgesehen), wird impliziert, dass die Kaskade ausgeführt wird Normale Platzierung, da in der Spezifikation lediglich angegeben wird, dass Stile in allen @media - Regeln angewendet werden sollen, die dem Browser oder den Medien entsprechen.

93
BoltClock

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 habe jedoch festgestellt, dass dies keine gute Idee ist, da es auf Chrome derzeit weder auf meinem Ubuntu-Desktop noch auf meinem Android - Telefon 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!

calc() kann verwendet werden, um dieses Problem zu umgehen (min-width: 50em and max-width: calc(50em - 1px) 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, nicht die em -Einheit zu verwenden, würde beim Stapeln von Abfragen helfen.

3
Milche Patern