Меня зовут София. Я - CSS инженер. Это мой блог.

Если вам очень больно без стилей, вы можете их.

Вы уже слышали о вариативных юнитах?

Дисклеймер: перевод термина variable units еще не устоялся. Сейчас в этой статье я использую перевод вариативные юниты, потому что он нравится мне больше всего. Если вы хотите поучаствовать в обсуждении, приходите на гитхаб.

Недавно рабочая группа CSS начала работать над новой версий спецификации css-variables. Вариативные юниты должно стать первым большим нововведением.

История началась с твита Джонатана Нила, где он предложил дать разработчикам возможность создавать свои единицы измерения на основе css-переменных. Это работает примерно так:

:root {
  --size: 4px;
  /* переменная объявлена в корне документа */
}

.elem {
  width: calc(4 * (var(--size)));
  /* примерно так она может использоваться в коде */
}

.elem2 {
  width: 4--size;
  /* а так может выглядеть ее использование в виде пользовательского юнита */
}

.elem3 {
  width: var(--size);
  /* в то же время, это все еще просто переменная! */  
}

То есть, по сути, добавляет синтаксического сахара. Проще писать, проще читать.

Возможные примеры использования

Базовые размеры

Подход с базовыми размерами распространен в дизайн-системах и это будет удобной возможностью.

Переопределение базовых размеров

Поскольку это просто переменная, ее также можно переопределять, и единица измерения тоже изменится:

:root {
  --bs: 4px; /* base size */
}

.module {
  margin-block: 1.5--bs;
  border-block: .5--bs;
  /* задаем границы и отступы блоку */
}

.sidebar .module {
  --bs: 6px;
  /* делаем границы и отступы чуть поменьше в сайдбаре */
}

Удобное указание размера шрифта

Наверняка многие из вас знают популярный адаптивный способ записи размера шрифта с помощью функции clamp() :

.fluid-type {
  font-size: clamp(10px, 1vw + 1vh, 1rem);
}

Здесь указывается минимальный, максимальный и промежуточный меняющийся размер. Подробнее на CSS TRICKS.

Теперь мы можем создать юнит, равный этому значению и удобно использовать его в коде:

:root {
  --fem: clamp(10px, 1vw + 1vh, 1rem);
}

.fluid-type {
  font-size: 1.2--fem;
}

Юниты лучше типизировать

В отличии от функции var() в случае использования переменной как вариативного юнита вы не можете указать резервное значение. Поэтому, если переменная не определена или определена как единица длины, все значение юнита будет невалидным. Это логично, ведь вариативные юниты - это просто синтаксических сахар над calc().

Например:

.elem2 {
  width: 4--bs;
  /* переменная не объявлена в документе и указанное значение будет невалидным. */
  /* то есть значение ширины для этого элемента возьмется ниже из каскада */
}

Или так:

:root {
  --bs: red;
}
.elem3 {
  width: 4--bs;
  /* тип переменной не соответствует типу свойства и ситуация будет аналогичной */  
}

Поэтому, лучше всего типизировать ваши переменные. Это гарантирует, что у переменной всегда будет резервное значение. Например:

@property --fem { /* типизировали переменную */
  syntax: "<length>";
  initial: clamp(10px, 1vw + 1vh, 1rem);
  /* задали начальное значение */
  inherits: true;
}

:root {
  --fem: red;
  /* ошиблись и записали в это переменную цвет */
}

.fluid-type {
  font-size: 1.2--fem; /* выражение все равно будет корректно работать */
}

Подробнее о типизации переменных можно прочитать здесь.

А если делать это через js, а не через директиву @property, то вы точно увидите ошибку.

Источники

  1. Черновик новой версии спецификации.
  2. Недавняя статья от Bramus.
  3. Обсуждение на гитхабе от Таба Аткинса.