«У всякой проблемы всегда есть решение — простое, удобное, и конечно ошибочное«. — Генри Луис Менкен.
Суть проблемы
На первый взгляд реализация адаптивной верстки может показаться «линейным квестом » с довольно небольшим полем для маневров.
Назначаем нужные классы, меняем по мере надобности размеры, положение или порядок элементов и дело вроде бы сделано.
Но время от времени анализируя вёрстку в полностью завершенных проектах, невольно ловишь себя на мысли, что в теории все выглядит гораздо лучше чем на практике. На старте css выглядит максимально ухоженно и логично, но чем его больше тем он обычно запущенее, особенно после нескольких правок с большими временными промежутками.
При столкновении с необычными дизайнерскими решениями медиа запросы становятся «толще», появляются нестандартные брейкпоинты, а при смене деталей дизайна, внесение правок в вёрстку становится довольно тяжелой работой.
Любая поправка от клиента или дизайнера, и css код нужно редактировать во всех медиа запросах (особенно если это чужой css и они разбросаны по всему коду в разных местах с нелогичной последовательностью).
Что часто приводит к ситуации когда вы уже не совсем контролируете ситуацию и появляется соблазн прибегнуть к «жёстким» методам, таким как директива !important, или вложенность. Код становится ещё менее настраиваемым и где-то там среди тысяч строк появляются строки которые уже не нужны и только (пусть и незначительно ) замедляют работу браузера.
Решение
Часть 1. Абсолютная относительность
Основная и важнейшая мысль этой статьи в том что чем меньше css кода мы пишем тем легче его контролировать.
Суть метода обратной адаптивности в том — что бы сделать каждый элемент максимально адаптивным, после чего постепенно уменьшать его способность приспосабливаться к размерам экрана.
Итак главный шаг к этому — это использование абсолютных единиц измерения: px, em, rem только внутри медиа запросов (за редкими исключениями).
Вне медиа запросов нам лучше пользоваться только относительными viewport единицами измерения: vw, vh, vmax и процентами %.
Корневые теги блоков и текст мы будем измерять во viewport единицах, для дочерних же, размер удобнее считать в процентах от родительского.
Звучит логично — позволить элементам адаптироваться к размерам экрана самостоятельно, не переписывая настройки для каждого брейкпоинта.
Каждый раз работу стоит начинать с подготовки в независимости от размеров проекта.
Первое что мы сделаем это измерим наш пример макета и запишем все нужные нам размеры.

1920 — это главная ширина нашего макета, от нее будут зависеть все остальные размеры по горизонтали.
930 — это главная высота нашего макета (предполагаемая высота одновременно видимой на экране области страницы), от нее будут зависеть все размеры по вертикали.
1400 — это ширина контейнера, в который будет упаковываться всё содержимое страницы.
Далее создадим основные классы для контейнера и текста, следующим образом:
(Вычисляемая ширина / ширина макета) * 100, т.е. в нашем случае
(1400 / 1920) * 100 = 72.9
Результат как и планировалось выше запишем во viewport единицах а именно view width:
.container { width: 72.91vw; }
Тоже самое проделаем для текста за тем исключением, что вместо vw используем vmax — что бы использовать максимальный размер экрана а не ширину.
(55 / 1920) * 100 = 2.86
.page__title { font-size: 2.86vmax; }
Так же для элементов у которых совпадает значение высоты и ширины (квадратные и круглые элементы) тоже нужно использовать vmax единицы что бы сохранять пропорции. Далее можно приступить к верстке и набросать сетку.
Для блоков которым нужно задать высоту используем ту же формулу пересчёта во viewport, но теперь вместо ширины мы будем будем отталкиваться от высоты экрана и к результату дописывать vh(view height). Так же к верхним и нижним отступам мы будем применять vh.
(300 / 1920) * 100 = 15.62;
(60 / 1920) * 100 = 3.12;
.main__block { width: 15.62vmax; height: 15.62vmax; margin-top: 3.12vh; margin-right: 3.12vw; }
А ширину вложенных блоков как я говорил ранее мы посчитаем в процентах используя flex-basis.

(970 / 1920) * 100 = 50.52;
(16 / 1920) * 100 = 0.83;
.main-menu { width: 50.52vw; } .main-menu__item { flex-basis: calc(100% / 4 - 0.83vw); }
Часть 2. Обратная адаптивность
Блоки ведут себя максимально адаптивно, но они адаптивны чрезмерно:
текст становиться нечитаемым на маленьких экранах, а блоки готовы сужаться до бесконечности, на любом экране.
Теперь настало время для обратной адаптивности.
Используя медиа запросы мы заменяем относительные единицы на абсолютные.
Em для Размера шрифта;
Px для высоты блоков;
Для ширины контейнера и некоторых блоков мы продолжим использовать относительные единицы но сменим их на %:
@media (max-width: 767px) { .page__title { font-size: 4em; } .main__block { width: 300px; height: 300px; } .some__block { width: 100%; height: 300px; } .... }
Таким образом при одном единственном медиа запросе мы сменили view port единицы измерения на абсолютные, тем самым частично остановив процесс адаптации.
Важный плюс — теперь за счёт относительных единиц измерения верстка будет одинаково выглядеть как на экране ноутбука, так на экране огромной плазменной панели.
Часть 3. Удобство и щепотка программирования
При всей универсальности данного метода мы продолжаем делать много работы «за кадром», а именно бесконечно пользоваться калькулятором для перевода пикселей во viewport единицы «вручную». Что бы автоматизировать этот процесс нам понадобиться выполнить несколько простых шагов с помощью Scss:
1. Записать главные размеры в переменные
$full-width: 1920; $work-width: 80; $screen-height: 720;
2. Написать функцию для автоматичемкого пересчёта пикселей во viewport
@function vmax($pixels, $context: $full-width) { @return #{($pixels/$context)* 100}vmax }
и две аналогичные для vw и vh.
Теперь мы можем смело писать все размеры в том виде в котором они указаны в макете примера и не считать это «вручную»:
.main__block { width: vmax(300); height: vmax(300); margin-top: vh(60); margin-right: vw(60); }
Тем самым мы экономим время и силы.
Выше в медиа запросах мы использовали единицы em для указания размеров шрифта,
поэтому неплохо было бы написать функцию и для них, что соблюдать четкость и порядок:
$browser-context: 16; @function em($pixels, $context: $browser-context) { @return #{$pixels/$context}em }
Думаю вполне очевидно что эти функции будут написаны один раз и далее могут «переезжать» из одного проекта в другой, вместе с созданными переменными, а так же некоторыми классами зависящими от них.
Единственное что придется делать начиная работу над новым проектом это снова «снять мерку» с макета и подмена значений в этих переменных.
Заключение
- Мы получаем минимум лишнего кода разбросанного в разных концах и файлах.
- Увеличиваем свой контроль над ним.
- Ускоряем процесс написания и редактирования кода.
- Банально упрощаем себе жизнь, ведь как показывает практика — меньше кода = меньше проблемм.
ссылка на оригинал статьи https://habr.com/post/420105/
Добавить комментарий