Немного о media-queries и брейкпойнтах

Бонус: Breakpoints как в SASS, но только в LESS

Одна из самых часто встречающихся ошибок в использовании media-queries — это жесткое задание трех-четырёх точек перелома (или брейкпойнтов, как угодно). Понятно, откуда она возникает — большинство популярных фреймворков работает именно так. Более того, большинство популярных сеток работает именно так. И дело даже не в количестве этих точек, а в самом принципе — вот есть n точек, их и используй. Но ведь сам подход в корне неверен. Что, если какую-то часть страницы для оптимального отображения нужно изменять не от 700px, например, а от 600? Добавлять еще одну переменную? Нет, чаще верстальщик меняет элемент от 700px, и даже не думает о том, что некоторые пользователи, у которых ширина браузера, скажем, 680px (половина от горизонтального размера одного из самых популярных разрешений), будут видеть мешанину.

Именно поэтому нужно как о страшном сне навсегда забыть про жестко заданные точки перелома. Единственный вариант — это более-менее индивидуальная работа над элементами. Но каждый раз писать по миллиону разных правил весьма утомительно, не так ли? Тут на помощь приходят препроцессоры.

Недавно был впечатлён возможностями библиотечки breakpoint для SASS. Если коротко — она делает процесс написания media queries в разы проще. Передаешь один параметр — получаешь @media (min-width: %параметр%). Передаешь два — получаешь min-width и max-width. Ну и так далее. Быстрый гуглинг не показал ничего похожего для LESS.

К счастью, LESS умеет в JS (и это то самое главное в LESS, что делает его, как мне кажется, гораздо более полезным для фронтендера, чем SASS), поэтому написать собственный миксин не составит труда.

Сам миксин (там же есть развернутая версия с комментариями):

Опишу примеры использования. По сути миксин умеет всё то же, что и breakpoint-sass, кроме того, что описано в последнем абзаце. То есть никаких дефолтных значений (почти), никакой особой поддержки device-pixel-ratio (ребята, это умеет делать Post CSS).

.test {
    .breakpoint(450px, {
        color: #fff;
    });
}
=>
@media only screen and (min-width: 450px) {
  .test {
    color: #fff;
  }
}

В случае, когда используются два параметра, я решил для второго использовать min-height, потому что mobile-first, все дела. Мне так проще.

.test {
    .breakpoint(~"450px 500px", {
        color: #fff;
    });
}
=>
@media only screen and (min-width: 450px) and (min-height: 500px) {
  .test {
    color: #fff;
  }
}

Если первый параметр не содержит в себе никаких цифр, он станет правилом, а второй параметр — значением.

.test {
    .breakpoint(~"max-width 1000px", {
        color: #fff;
    });
}
=>
@media only screen and (max-width: 1000px) {
  .test {
    color: #fff;
  }
}

С помощью скобок правила можно комбинировать.

.test {
    .breakpoint(~"(min-height 1000px) (orientation portrait)", {
        color: #fff;
    });
}
=>
@media only screen and (min-height: 1000px) and (orientation: portrait) {
  .test {
    color: #fff;
  }
}

Благодаря этому возможны, например, такие сокращения:

.test {
    .breakpoint(~"(1000px 500px) (orientation portrait)", {
        color: #fff;
    });
}
=>
@media only screen and (min-width: 1000px) and (min-height: 500px) and (orientation: portrait) {
  .test {
    color: #fff;
  }
}

Обратите внимание, что в качестве параметра должна передаваться экранированная строка. В LESS экранирование работает так: ~"строка". Для одиночных параметров это не критично, но в случае, когда в передаваемой строке есть пробелы — обязательно.

Комментариев к “Немного о media-queries и брейкпойнтах”: 4

  1. А как насчет max-width? Может чего не понял, но всякие «.breakpoint(~»(1000px 500px)» показались какими-то не слишком удобными затычками. Писать слишком много и не слишком очевидно.
    Думаю, если бы можно было писать вроде «@media mw450 mh500 mxw700 mxh800» и в итоге получить «@media only screen and (min-width: 450px) and (min-height: 500px) and (max-width: 700px) and (max-height: 800px) » было бь гораздо лаконичнее и проще.

  2. Тренинги, статbи, обyчeние зapaбoткy в интеpнeтe и многоe дрyгоe. Выплaченo зa сeгодня: 475 957.52 рyб. Tyт всe оченb пpосто!

Добавить комментарий