Почему порядок медиа-запросов имеет значение в CSS?

80

В последнее время я разрабатывал более отзывчивые сайты и часто использовал медиа-запросы CSS. Я заметил одну закономерность: действительно имеет значение порядок, в котором определяются медиа-запросы. Я тестировал его не в каждом браузере, а только в Chrome. Есть ли объяснение такому поведению? Иногда становится неприятно, когда ваш сайт работает не так, как должен, и вы не уверены, это запрос или порядок, в котором он написан.

Вот пример:

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;}
}

Однако, если бы я написал запрос для 1024x600 в последнем, браузер проигнорирует его и применит значение поля, указанное в начале CSS (margin-top: 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;}
}

Если я правильно понимаю медиа-запросы, порядок не имеет значения, но похоже, что это так. Что может быть причиной?

dsignr
источник

Ответы:

139

Это сделано с помощью CSS - Cascading Style Sheet.

Это означает, что если вы примените два правила, которые сталкиваются с одними и теми же элементами, он выберет последнее из объявленных, если только первое не имеет !importantмаркера или не является более конкретным (например, html > bodyvs just body, последнее менее конкретное).

Итак, учитывая этот CSS

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

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

если окно браузера имеет ширину 350 пикселей, фон будет синим, а с этим CSS

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

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

и такой же ширины окна, фон будет красным. Оба правила действительно совпадают, но применяется второе, потому что это последнее правило.

Наконец, с

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

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

или же

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

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

фон будет синим (с окном шириной 350 пикселей).

Алессандро Вендрусколо
источник
12
Спасибо. Я никогда не думал, что такая простая логика испортит мне сон на ночи вместе. Благодарю.
dsignr
В таблице стилей, если те же правила применяются без какого-либо медиа-запроса, а затем в медиа-запросе для мобильных устройств с маленьким экраном и есть некоторые изображения для загрузки. Итак, что произойдет, будет ли браузер игнорировать правила без медиа-запроса и применять только определенные правила медиа-запроса?
19

Или вы можете просто добавить минимальную ширину к большим медиа-запросам и не иметь никаких проблем, независимо от порядка.

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

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

При использовании этого кода в любом порядке цвет фона всегда будет красным для разрешений с шириной 400,1–600 пикселей и всегда будет синим для разрешений с шириной 400 пикселей или меньше.

Лиран Х
источник
9
Я съеживаюсь при виде значения вроде 400,1 пикселей в CSS. Или 1023px, 1025px и т. Д.
Monstieur