Все верстальщики рано или поздно сталкивались с болью, которая заключается в адаптиве сайта под различные устройства. Существуют разные технологии, упрощающие подгонку размеров под определённые устройства, например, clamp()
. Эта функция удобна, так как позволяет минимизировать использование брейкпоинтов, но у неё есть свои недостатки:
Код сложнее читается и редактируется.
Необходимо указывать
clamp
для каждого элемента с изменяющимися размерами, постоянно высчитывая и подбирая значения.Требуется продумывать, где использовать, а где нет, что создаёт отсутствие чёткой системности.
Сложности с чётким заданием размеров для промежуточных брейкпоинтов, например, для планшетов.
Делаем разработку проще
На помощь приходят старые добрые rem’ы. Этот подход не новый, но он простой в разработке и, самое главное, удобный для разработчика. Перейдём к сути.
Для удобства будем использовать функцию rem()
, которая переводит пиксели в rem:
@function rem($pixels) {
@return calc($pixels / 10) + rem;
}
Та самая формула, которая высчитывает значение 1rem. Для удобства мы будем отталкиваться от значения 10px, модифицируя его с помощью формулы:
html {
--refRes: 1920;
font-size: calc(100vw / var(--refRes) * 10);
@media (max-width: 1024px) {
--refRes: 768
}
@media (max-width: 530px) {
--refRes: 320
}
}
Мы берём текущую ширину экрана, делим на базовое разрешение экрана, от которого отталкиваемся (1920px для десктопа), и умножаем на стандартное значение шрифта (10px)
На выходе получаем линейную зависимость значения шрифта от ширины экрана. Используя rem()
везде, все элементы также начинают зависеть от ширины экрана:
.foo {
width: rem(100);
height: rem(50);
font-size: rem(24);
}
Что примет вид:
.foo {
width: 10rem;
height: 5rem;
font-size: 2.4rem;
}
От 1920 до 1025 сайт выглядит как при 1920.
От 1024 до 531 сайт выглядит как при 768.
от 530 до 320 сайт выглядит как при 320.
Исходя из этого, нам не нужно переживать о том, как будет выглядеть сайт при промежуточных разрешениях — ничего не сломается.
Забота о братьях наших больших
Что же с разрешениями больше 1920?
В этом примере я взял разрешение в 2 раза больше, чем 1920, и тут видно, что все элементы тоже увеличились в 2 раза, что привело к тому, что всё выглядит, как будто у нас разрешение 1920, а не 3840.
Кто-то специально купил широкоформатный монитор и хочет, чтоб у него на экране помещалось больше контента, а мы его лишаем такого удовольствия.
Для этого есть решение:
html {
--refRes: 1920;
$ratio: 0.5;
font-size: calc(100vw / var(--refRes) * 10);
@media (min-width: 1921px) {
font-size: calc(
10px + ($ratio * 10) * ((100vw - var(--refRes) * 1px) / var(--refRes))
);
}
Добавляем переменную $ratio
, которая определяет скорость увеличения размеров у элементов.
С коэффициентом 0.5, при увеличении размера экрана в два раза элементы увеличиваются всего в 1.5 раза. Таким образом, ничего не ломается, и на экране помещается больше элементов.
Что мы в итоге имеем
Из плюсов:
Код легко читается.
Все значения указываются в понятном виде — так, как в макете.
Можно использовать более жёсткие методы расстановки элементов, чётко указывая, как они будут выглядеть на разных брейкпоинтах.
При разработке не нужно учитывать промежуточные размеры viewport.
Сайт всегда будет выглядеть так, как задумывалось, на любом размере экрана в пределах своей категории, определяемой брейкпоинтами и базовым разрешением.
Есть чёткая системность: использовать
rem()
всегда и везде, за исключением, где нужныem
,%
,ch
и другие единицы.
Из очевидных минусов:
Невозможность поменять размер шрифта в настройках браузера.
Зум через клавиши «+», «-» не меняет ничего в пределах между брейкпоинтами (пользователь не может немного увеличить размер страницы, может только использовать заранее подготовленные версии сайта).
При разработке необходимо вручную записывать все меняющиеся значения по брейкпоинтам.
Заключение
Таким образом, мы сделали все размеры элементов зависимыми от font-size
у html-элемента, что придало им резиновость, а нам — удобство в разработке.
Буду рад вашим обсуждениям этой темы, и, возможно, вместе мы сделаем жизнь верстальщиков немного проще.
Материалы к статье
Репозиторий с примером.
Страница с примером.
-
Статьи с похожей темой:
Комментарии (5)
kellas
05.06.2024 07:05+1Интересный подход, для новостных сайтов может не лучший выбор, а вот для приложений самое то! Спасибо!
ooko
05.06.2024 07:05+1Для десктопа так делать не советую. Ну можно для маленькой ширины, но это когда адаптировать совсем лень. Удобно использовать для телефона, планшета или телевизора.
Много лет использую этот прием с rem. Даже делал доклад на MoscowJS. Это по сути получается векторная графика - и соответственно получаем проблему дробных пикселей у маленьких элементов. Это линии в один пиксель или когда нужно выравнивать что-то по вертикали .
Из минусов - нужно постоянно помнить что верстаешь векторную графику. В коде js тоже нужно это помнить. Всем картинкам не забывать указывать размер.
Кому интересно как работает могут посмотреть тут https://ooko.pro . Только нужно через телефон или в инспекторе включить мобильный и перезагрузить. Так как учитываю агент браузера.
RomkaLis
05.06.2024 07:05Прочитал с интересом, но, на мой взгляд, минусы для пользователя полностю перекрывают плюсы для разработчика. Мы все же сайты делаем, для того, чтобы люди их смотрели, по возможности, с комфортом. Говорю как человек постоянно пользующийся + / -.
savostin
Здорово конечно. Разработчику. Но сайт с такими минусами вызывает у меня глубокое отторжение.