Warum ist die Reihenfolge der Medienabfragen in CSS wichtig?

80

In letzter Zeit habe ich Websites entworfen, die reaktionsschneller sind, und ich habe häufig CSS-Medienabfragen verwendet. Ein Muster, das mir aufgefallen ist, ist, dass die Reihenfolge, in der die Medienabfragen definiert werden, tatsächlich von Bedeutung ist. Ich habe es nicht in jedem einzelnen Browser getestet, sondern nur in Chrome. Gibt es eine Erklärung für dieses Verhalten? Manchmal wird es frustrierend, wenn Ihre Site nicht ordnungsgemäß funktioniert und Sie nicht sicher sind, ob es sich um die Abfrage oder die Reihenfolge handelt, in der die Abfrage geschrieben wird.

Hier ist ein Beispiel:

HTML

<body>
    <div class="one"><h1>Welcome to my website</h1></div>
    <div class="two"><a href="#">Contact us</a></div>
</body>

CSS:

body{
font-size:1em; /* 16px */
}

.two{margin-top:2em;}



/* Media Queries */

@media (max-width: 480px) {
    .body{font-size: 0.938em;}

}
/* iphone */
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
    body {font-size: 0.938em;}
}
/*if greater than 1280x800*/
@media (min-width: 1200px) {
       .two{margin-top:8em;}
            }
/*1024x600*/
@media (max-height: 600px) {
       .two{margin-top:4em;}
}
/*1920x1024*/
@media (min-height: 1020px) {
       .two{margin-top:9em;}
}
/*1366x768*/
@media (min-height: 750px) and (max-height: 770px) {
       .two{margin-top:7em;}
}

Wenn ich jedoch die Abfrage für 1024 x 600 im letzten geschrieben habe, würde der Browser sie ignorieren und den am Anfang des CSS angegebenen Randwert anwenden (Rand oben: 2em).

/* Media Queries - Re-arranged version */

@media (max-width: 480px) {
    .body{font-size: 0.938em;}
}
/* iphone */
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
    body {font-size: 0.938em;}
}
/*if greater than 1280x800*/
@media (min-width: 1200px) {
       .two{margin-top:8em;}
}
/*1920x1024*/
@media (min-height: 1020px) {
       .two{margin-top:9em;}
}
/*1366x768*/
@media (min-height: 750px) and (max-height: 770px) {
       .two{margin-top:7em;}
}
 /*1024x600*/
@media (max-height: 600px) {
       .two{margin-top:4em;}
}

Wenn mein Verständnis von Medienabfragen korrekt ist, sollte die Reihenfolge keine Rolle spielen, aber es scheint so. Was könnte der Grund sein?

dsignr
quelle

Antworten:

138

Dies ist das Design von CSS - Cascading Style Sheet.

Wenn Sie zwei Regeln anwenden, die auf dieselben Elemente kollidieren, wird die letzte deklariert, die deklariert wurde, es sei denn, die erste hat die !importantMarkierung oder ist spezifischer (z. B. html > bodygegen nur body, die letztere ist weniger spezifisch).

Also, angesichts dieses CSS

@media (max-width: 600px) {
  body {
    background: red;
  }
}

@media (max-width: 400px) {
  body {
    background: blue;
  }
}

Wenn das Browserfenster 350 Pixel breit ist, ist der Hintergrund bei diesem CSS blau

@media (max-width: 400px) {
  body {
    background: blue;
  }
}

@media (max-width: 600px) {
  body {
    background: red;
  }
}

Bei gleicher Fensterbreite ist der Hintergrund rot. Beide Regeln stimmen zwar überein, aber die zweite Regel wird angewendet, weil es sich um die letzte Regel handelt.

Zum Schluss mit

@media (max-width: 400px) {
  body {
    background: blue !important;
  }
}

@media (max-width: 600px) {
  body {
    background: red;
  }
}

oder

@media (max-width: 400px) {
  html > body {
    background: blue;
  }
}

@media (max-width: 600px) {
  body {
    background: red;
  }
}

Der Hintergrund ist blau (mit einem 350 Pixel breiten Fenster).

Alessandro Vendruscolo
quelle
11
Vielen Dank. Ich hätte nie gedacht, dass eine so einfache Logik meinen Schlaf für Nächte zusammen ruinieren würde. Vielen Dank.
dsignr
Wenn in einem Stylesheet dieselben Regeln ohne Medienabfrage und dann in einer Medienabfrage für mobile Geräte mit kleinem Bildschirm angewendet werden und einige Bilder heruntergeladen werden müssen. Was würde also passieren? Ignoriert der Browser die Regeln ohne Medienabfrage und wendet nur die Regeln bestimmter Medienabfragen an?
19

Oder Sie können den größeren Medienabfragen nur eine minimale Breite hinzufügen und haben unabhängig von der Reihenfolge keine Probleme.

@media (min-width: 400.1px) and (max-width: 600px) {
  body {
    background: red;
  }
}

@media (max-width: 400px) {
  body {
    background: blue;
  }
}

Wenn Sie diesen Code in beliebiger Reihenfolge verwenden, ist die Hintergrundfarbe bei Auflösungen mit einer Breite von 400,1 bis 600 Pixel immer rot und bei Auflösungen mit einer Breite von 400 Pixel oder weniger immer blau.

Liran H.
quelle
9
Ich erschrecke beim Anblick eines Wertes wie 400.1px in CSS. Oder 1023px, 1025px usw.
Monstieur