Каковы правила перекрытия медиа-запросов CSS?

Как мы точно распределяем медиа-запросы, чтобы избежать перекрытия?

например, если мы рассмотрим код:

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

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

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

что произойдет во всех поддерживаемых браузерах ровно в 20em и 45em?

Я видел, как люди используют: такие вещи, как 799px, а затем 800px, но как насчет ширины экрана 799.5 px? (Очевидно, не на обычном дисплее, а на сетчатке?)


Мне очень интересно узнать ответ здесь учитывая спецификацию.

3 ответов


каковы правила перекрытия медиа-запросов CSS?

Каскад.

@media правила прозрачны для каскада, поэтому, когда два или более @media правила совпадают в то же время браузер должен применять стили во всех правилах, которые совпадают, и соответственно разрешать каскад.1

что произойдет во всех поддерживаемых браузерах ровно в 20em и 45em?

At ровно 20em широкий, ваш первый и второй медиа-запрос будет соответствовать. Браузеры будут применять стили в обоих @media правила и каскад соответственно, поэтому, если есть какие-либо конфликтующие правила, которые необходимо переопределить, последний объявленный выигрывает (с учетом конкретных селекторов,!important и т. д.). Аналогично для второго и третьего медиа-запроса, когда окно просмотра имеет ширину 45em.

учитывая ваш пример кода, с некоторыми фактическими правилами стиля добавлены:

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

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

когда окно просмотра браузера имеет ширину ровно 20em, оба этих медиа-запроса вернут true. У Каскада, display: block переопределяет display: none и float: left будет применяться к любому элементу с классом .sidebar.

вы можете думать об этом как о применении правил, как если бы медиа-запросов не было с самого начала:

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

еще один пример того, как каскад происходит, когда браузер соответствует двум или более Медиа-запросам, можно найти в этот и другие ответ.

имейте в виду, что если у вас есть объявления, что не перекрытие в обоих @media правила, то все эти правила будут применяться. То, что здесь происходит, - это Союз деклараций в @media правила, а не только последнее полностью отменяет первое... что подводит нас к вашему предыдущему вопросу:

как мы размещаем медиа-запросы точно, чтобы избежать перекрытия?

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

помните, что min- и max- префиксы означают "минимальный инклюзивный" и "максимальный инклюзивный"; это означает (min-width: 20em) и (max-width: 20em) оба матча с просмотра именно 20em широкий.

похоже, у вас уже есть пример, который подводит нас к вашему последнему вопросу:

я видел, как люди используют: такие вещи, как 799px, а затем 800px, но как насчет ширины экрана 799.5 px? (Очевидно, не на обычном дисплее, а на сетчатке?)

это я не совсем уверен; все значения пикселей в CSS являются логическими пикселями, и мне было трудно найти браузер, который сообщал бы дробное значение пикселя для ширины окна просмотра. Я пробовал экспериментировать с некоторыми iframes, но не смог ничего придумать.

из моих экспериментов казалось бы, Safari на iOS округляет все дробные значения пикселей чтобы убедиться, что один из max-width: 799px и min-width: 800px будет соответствовать, даже если окно просмотра действительно 799.5 px (что, по-видимому, соответствует первому).


1хотя ничто из этого явно не указано ни в модуль условных правил или модуль "Каскад" (последний из которых в настоящее время запланирован для перезаписи), каскад подразумевается, что происходит нормально, поскольку спецификация просто говорит о применении стилей в любом и все!--2--> правила, соответствующие браузеру или носителю.


calc() можно использовать для работы вокруг этого (min-width: 50em and max-width: calc(50em - 1px) будет правильно уложен), но плохая поддержка браузера, и я бы не рекомендовал его.

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

информация:

некоторые другие упомянутые, не используя em блок помог бы в ваши запросы укладки.


Я пробовал как рекомендовано здесь:

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

но обнаружил, что это не была хорошая идея, потому что она не работает на Chrome прямо сейчас ни на моем рабочем столе Ubuntu или на моем телефоне Android. (как объясняется здесь:calc () не работает в медиа-запросах) но я нашел лучший способ...

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

и бац!