Азат Ш.

Резиновые интерфейсы

Резиновые интерфейсы

18 августа 2022 г.

4 минуты на прочтение

Также переведено на:

Современный веб — зоопарк всевозможных устройств, на которых можно запустить браузер. Поэтому разработчики следят за тем, как сайт выглядит на разных мобильных устройствах, планшетах и настольных компьютерах.

Из-за маленьких экранов мобильных устройств стоит сокращать размер шрифтов и отступов на странице.

Самый распространённый способ это сделать — медиавыражения. Например:

css
.button {
  padding-inline: 4px;
  font-size: 1.25rem;
  background: blue;
  border: none;
  border-radius: 4px;
}

@media screen and (width >= 760px) {
  .button {
    padding-inline: 12px;
    font-size: 1.5rem;
    border-radius: 6px;
  }
}

У этого способа есть недостатки:

  • приходится писать много кода
  • хочется учитывать промежуточные значения для отступов и делать элементы на странице по-настоящему резиновыми

Допустим, задача — задать размер шрифта, который будет меняться в диапазоне от 480 до 1280 пикселей. Минимальный размер будет 2.25rem, максимальный - 3rem.

Какие есть способы это сделать?

Функция calc()

Эта функция используется для вычислений в CSS. В сочетании с единицей измерения vi (процентная величина ширины области просмотра), она становится мощным инструментом для создания адаптивного интерфейса.

Определим разницу между максимальным и минимальным размерами шрифта. В нашем примере это будет: 3rem - 2.25rem = 0.75rem.

Также определим разницу между значениями вьюпорта, предварительно преобразовав их значение в единицу rem (зависит от значения <html>, по‑умолчанию 16px). Получаем (1280 / 16) - (480 / 16) = 50.

Мы получили следующие значения:

  • Минимальный размер шрифта: 2.25rem
  • Максимальный размер шрифта: 3rem
  • Разница между максимальным и минимальным размерами шрифта: 0.75rem
  • Минимальный размер вьюпорта: 30rem (480px)
  • Разница между максимальным и минимальным размерами вьюпорта: 50rem (800px)

Необходимая функция выглядит следующим образом:

Минимальный размер шрифта + Разница между максимальным и минимальным размерами шрифта * ((Ширина вьюпорта - Минимальный размер вьюпорта) / Разница между максимальным и минимальным размерами вьюпорта).

Итого получаем следующий результат:

css
.foo {
  font-size: 2.25rem;
}

@media screen and (min-width: 480px) and (max-width: 1280px) {
  .foo {
    font-size: calc(2.25rem + 0.75 * ((100vi - 30rem) / 50));
  }
}

@media screen and (min-width: 1280px) {
  .foo {
    font-size: 3em;
  }
}

Стало лучше, но пока кода по-прежнему слишком много.

Функция clamp()

Функция clamp() - более лаконичный способ задания значения в диапазоне между минимальным и максимальным значением CSS свойства.

Всё, что остаётся - это найти предпочитаемое значение размера шрифта.

График функции clamp

На координатной плоскости по оси X располагаются значения ширины окна браузера, а по оси Y - значения CSS свойств. Определим точку пересечения графика функции с осью ординат. Для этого используется угловой коэффициент.

Угловой коэффициент, напомню, это отношение изменения координаты Y (двух точек) к изменению координаты X (двух точек). Найдём разность между значениями которые соответствуют координатам первой и второй точек. Разницу между максимальным и минимальным размерами шрифта разделим на разницу между максимальным и минимальным размерами вьюпорта (одновременно с этим конвертируем размеры вьюпорта из px в rem для удобства). Результат: (3 - 2.25) / ((1280 / 16) - (480 / 16)) = 0.015

Угловой коэффициент равен 0.015. Теперь найдём пересечение по оси Y по формуле: минимальный размер вьюпорта, преобразованный в отрицательное число, умноженный на угловой коэффициент плюс минимальный размер шрифта: (0 - (480 / 16)) * 0.015 + 2.25 = 1.8

Предпочитаемое значение размера шрифта будет равно пересечению по оси Y + (угловой коэффициент * 100)vi.

css
.foo {
  font-size: clamp(2.25rem, 1.8rem + 1.5vi, 3rem);
}

PostCSS плагин

postcss-responsive >

Эта математика кажется утомительной, особенно если речь идёт о разработке большого веб-приложения или целой дизайн-системы.

Чтобы упростить задачу я создал соответствующий плагин postcss-responsive.

Для использования резиновой типографики в проекте достаточно установить PostCSS-плагин:

bash
npm install --save-dev postcss-responsive
bash
pnpm add --save-dev postcss-responsive
bash
yarn add --dev postcss-responsive

Добавляем плагин в PostCSS конфиг:

json
{
  "plugins": {
    "postcss-responsive": {
      "minWidth": 480,
      "maxWidth": 1280
    }
  }
}

Теперь можно использовать функцию responsive() в наших стилях, передав в неё минимальный и максимальный размеры шрифта. Значение вычислит PostCSS-плагин.

postcss
/* Input */

.foo {
  font-size: responsive(2.25rem, 3rem);
}

/* Output */

.foo {
  font-size: clamp(2.25rem, 1.8rem + 1.5vw, 3rem);
}

Этот плагин будет полезен не только для создания адаптивной типографики, но и для работы с другими свойствами CSS.

postcss
.container {
  display: grid;
  grid-template-columns: responsive(180px, 240px) 1fr;
  grid-gap: responsive(8px, 16px);
  padding: responsive(16px, 32px) responsive(16px, 24px);
  font-size: responsive(1rem, 1.125rem);
  line-height: responsive(1.5rem, 1.75rem);
}

Создавайте резиновые интерфейсы без медиавыражений.

Отредактировать эту страницу

Следующая статья

Нейтрализуем издержки сетей