Как точно распределить медиа-запросы, чтобы избежать дублирования?
Например, если мы рассмотрим код:
@media (max-width: 20em) {
/* for narrow viewport */
}
@media (min-width: 20em) and (max-width: 45em) {
/* slightly wider viewport */
}
@media (min-width: 45em) {
/* everything else */
}
Что будет происходить во всех поддерживающих браузерах ровно при 20 и 45 em?
Я видел, как люди использовали: 799 пикселей, а затем 800 пикселей, но как насчет ширины экрана 799,5 пикселей? (Явно не на обычном дисплее, а на сетчатке?)
Меня больше всего интересует ответ, учитывая спецификацию.
max-width: 20em
определения, а затем также применил быmin-width: 20em
определения.Ответы:
Каскад.
@media
правила прозрачны для каскада, поэтому, когда два или более@media
правила совпадают одновременно, браузер должен применить стили во всех правилах, которые соответствуют, и соответствующим образом разрешить каскад. 1При ширине ровно 20em ваш первый и второй медиа-запросы будут совпадать. Браузеры будут применять стили как в
@media
правилах, так и в каскаде соответственно, поэтому, если есть какие-либо конфликтующие правила, которые необходимо переопределить, побеждает последнее объявленное (с учетом определенных селекторов!important
и т. Д.). То же самое для второго и третьего медиа-запроса, когда ширина области просмотра составляет точно 45 мкм.Учитывая ваш пример кода, с добавлением некоторых фактических правил стиля:
@media (max-width: 20em) { .sidebar { display: none; } } @media (min-width: 20em) and (max-width: 45em) { .sidebar { display: block; float: left; } }
Когда окно просмотра браузера имеет ширину ровно 20 мкм, оба эти медиа-запроса вернут 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 в ширину.Похоже, у вас уже есть пример, который подводит нас к вашему последнему вопросу:
В этом я не совсем уверен; все значения пикселей в CSS являются логическими пикселями, и мне было трудно найти браузер, который сообщал бы дробное значение пикселя для ширины области просмотра. Я пробовал поэкспериментировать с некоторыми фреймами, но ничего не смог придумать.
Судя по моим экспериментам, Safari на iOS округляет все дробные значения пикселей, чтобы гарантировать совпадение одного из
max-width: 799px
иmin-width: 800px
, даже если область просмотра действительно составляет 799,5 пикселей (что, очевидно, соответствует первому).1 Хотя ничего из этого явно не указано ни в модуле Conditional Rules, ни в модуле Cascade (последний из которых в настоящее время планируется переписать), предполагается, что каскад будет происходить нормально, поскольку в спецификации просто говорится о применении стилей в любых и все
@media
правила, соответствующие браузеру или носителю.источник
Я пробовал, как рекомендовано здесь:
@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*/ }
и бац!
источник
calc()
можно использовать, чтобы обойти это(min-width: 50em and max-width: calc(50em - 1px)
будет правильно сложено), но плохая поддержка браузера, и я бы не рекомендовал это.@media (min-width: 20em) and (max-width: calc(45em - 1px)) { /* slightly wider viewport */ }
Информация:
Некоторые другие упомянули, что неиспользование
em
устройства поможет в стеке ваших запросов.источник
calc()
не является частью спецификации медиа-запроса и не будет работать.