- PVSM.RU - https://www.pvsm.ru -
"У всякой проблемы всегда есть решение — простое, удобное, и конечно ошибочное". — Генри Луис Менкен.
На первый взгляд реализация адаптивной верстки может показаться «линейным квестом » с довольно небольшим полем для маневров.
Назначаем нужные классы, меняем по мере надобности размеры, положение или порядок элементов и дело вроде бы сделано.
Но время от времени анализируя вёрстку в полностью завершенных проектах, невольно ловишь себя на мысли, что в теории все выглядит гораздо лучше чем на практике. На старте css выглядит максимально ухоженно и логично, но чем его больше тем он обычно запущенее, особенно после нескольких правок с большими временными промежутками.
При столкновении с необычными дизайнерскими решениями медиа запросы становятся «толще», появляются нестандартные брейкпоинты, а при смене деталей дизайна, внесение правок в вёрстку становится довольно тяжелой работой.
Любая поправка от клиента или дизайнера, и css код нужно редактировать во всех медиа запросах (особенно если это чужой css и они разбросаны по всему коду в разных местах с нелогичной последовательностью).
Что часто приводит к ситуации когда вы уже не совсем контролируете ситуацию и появляется соблазн прибегнуть к «жёстким» методам, таким как директива !important, или вложенность. Код становится ещё менее настраиваемым и где-то там среди тысяч строк появляются строки которые уже не нужны и только (пусть и незначительно ) замедляют работу браузера.
Основная и важнейшая мысль этой статьи в том что чем меньше 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;
margi-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);
}
Блоки ведут себя максимально адаптивно, но они адаптивны чрезмерно:
текст становиться нечитаемым на маленьких экранах, а блоки готовы сужаться до бесконечности, на любом экране.
Теперь настало время для обратной адаптивности.
Используя медиа запросы мы заменяем относительные единицы на абсолютные.
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 единицы измерения на абсолютные, тем самым частично остановив процесс адаптации.
Важный плюс — теперь за счёт относительных единиц измерения верстка будет одинаково выглядеть как на экране ноутбука, так на экране огромной плазменной панели.
При всей универсальности данного метода мы продолжаем делать много работы «за кадром», а именно бесконечно пользоваться калькулятором для перевода пикселей во 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)
margi-right: vw(60);
}
Тем самым мы экономим время и силы.
Выше в медиа запросах мы использовали единицы em для указания размеров шрифта,
поэтому неплохо было бы написать функцию и для них, что соблюдать четкость и порядок:
$browser-context: 16;
@function em($pixels, $context: $browser-context) {
@return #{$pixels/$context}em
}
Думаю вполне очевидно что эти функции будут написаны один раз и далее могут «переезжать» из одного проекта в другой, вместе с созданными переменными, а так же некоторыми классами зависящими от них.
Единственное что придется делать начиная работу над новым проектом это снова «снять мерку» с макета и подмена значений в этих переменных.
Автор: JohnyScript
Источник [1]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/css/289152
Ссылки в тексте:
[1] Источник: https://habr.com/post/420105/?utm_campaign=420105
Нажмите здесь для печати.