Играем с Infinity в CSS
infinity
. Когда я впервые узнал об этом, мозг озарило множество абсурдных возможностей. Давайте обсудим! Возможно, найдутся и практические варианты использования.Прежде чем мы приступим к работе, необходимо знать одно важное правило: infinity
можно использовать только внутри оператора calc()
. Итак, приступим.
Никогда больше не проиграете битву за z-index
Вам когда-нибудь требовалось, чтобы элемент отображался поверх всего остального, но постоянно растущая гонка вооружений z-index
заставляла прибегать к всё более высоким значениям z-index
?
Завершите битву. Используйте infinity
, чтобы получить максимально возможный z-index
и одержать победу навсегда.
В демо приведённом ниже, не существует возможного значения z-index
для синей карты, при котором она окажется выше фиолетовой карты с z-index: calc(infinity)
. Попробуйте!
Самый большой из возможных элементов
Что произойдёт, если вы создадите <div>
с width
и height
в infinity
пикселей?
.big {
width: calc(infinity * 1px);
height: calc(infinity * 1px);
}
Обратите внимание, что мы умножаем infinity
на 1px
, чтобы превратить её в длину пиксели.
Вот демонстрация, показывающая результат, с некоторыми дополнительными пометками, чтобы лучше понять, что происходит в браузере.
Значения в функции getComputedStyle()
— то, к чему применяются свойства CSS. Значения в функции getBoundingRect()
отражают реальный размер отображаемого <div>
в области просмотра. Вот фрагмент кода.
// getComputedStyle()
const computed = window.getComputedStyle(bigEl);
const computedWidth = computed.getPropertyValue('width');
const computedHeight = computed.getPropertyValue('height');
// getBoundingRect()
const rect = bigEl.getBoundingClientRect();
const rectWidth = rect.width + 'px';
const rectHeight = rect.height + 'px';
Во-первых, infinity
в CSS на самом деле не бесконечна. Это просто очень большое число. Моё разочарование неизмеримо, в отличие от infinity
в CSS.
На моей машине (Windows desktop с Chrome) общая площадь <div>
в демонстрации составляет 33 554 428px
в квадрате, что примерно равно 79 км2. Неплохо! Но и не бесконечно.
Разные бесконечности
Обратите внимание, что в последнем абзаце я сказал на моей машине
. Хотя infinity
поддерживается во всех основных браузерах, значение, в которое оно преобразуется, может не совпадать в разных браузерах и операционных системах.
Некоторые примеры из демонстрации выше:
- Chrome на macOS выдаёт
16 777 214px
по ширине и высоте, что вдвое меньше, чем в Windows. - Firefox сообщает о ширине
1,78957e+7px
при использовании функцииgetComputedStyle()
и8 947 849px
при использовании функцииgetBoundingRect()
. - Firefox даже не пытается использовать
height: calc(infinity * 1px)
— просто игнорирует его. Но установка height:17895697px
(наибольшая длина CSS, которую разрешает использовать Firefox) работает. Я не знаю, почему Firefox не разрешаетheight
с таким значением, как это происходит сwidth
.
Кроме того, infinity
может принимать различные значения в зависимости от того, с каким CSS-свойством вы его используете. Помните пример с z-index
? Значение infinity
там было 2 147 483 647
— одинаковое для всех браузеров, которые я тестировал, но отличающееся от различных значений width
и height
, только что увиденных нами.
Все эти странные значения для infinity
, конечно, выбраны не случайно — они обусловлены тем, как хранятся числа. Например, 2 147 483 647
— это 2<sup>31</sup>-1
, наибольшее возможное значение для знакового 32-битного целого числа.
Анимация до бесконечности
Что произойдёт, если вы попробуете анимировать элемент до infinity
, как в этом случае?
.interstellar {
animation: go 10s;
}
@keyframes go {
to { translate: calc(infinity * 1px); }
}
Оказывается, элемент немедленно переходит в конец анимации и остаётся там на протяжении всего времени. Таким образом, в данном случае элемент остаётся справа настолько далеко, насколько может выдержать браузер, в течение всех 10 секунд.
В этом есть смысл. На пути к бесконечности нет приращений. Доля от бесконечности всё равно остаётся бесконечностью. Поэтому для каждого кадра анимации анимированное значение равно бесконечности.
Что произойдёт, если задать бесконечную animation-delay
?
.interstellar {
animation-delay: calc(infinity * 1s);
}
Вы, наверное, догадываетесь. Анимация никогда не начинается.
Практические случаи использования infinity
Захотите ли вы когда-нибудь использовать infinity
в CSS? Возможно! Иногда нужно просто огромное значение (каким бы оно ни было), и infinity
может его дать.
Например, вы можете придать форму пилюли, используя border-radius
со значением длины (не в процентах). Использование значения, большего, чем нужно, не изменит форму и будет хорошей идеей на случай, если элемент изменит размер.
div {
border-radius: calc(infinity * 1px);
}
Ещё одно возможное применение — это распространённый CSS сниппет, используемый, чтобы сделать контент "только для устройств чтения с экрана", расположив его далеко за пределами страницы.
.screen-reader-only {
position: absolute;
left: calc(infinity * -1px);
/* и остальное */
}
Но действительно ли infinity
лучше, чем большое произвольно значение, например 9999px
? Функционально — нет. Конечный результат тот же. Но думаю, это помогает сделать код более самодокументированным, потому что infinity
передаёт смысл. Она выражает, что всё дело в величине, а не в конкретном магическом числе.
Деление на ноль и отрицательные значения
Деление на ноль даст infinity
. Другими словами, calc(1 / 0)
и calc(infinity)
— это одно и то же. Это также работает с единицами измерения. Так, можно сделать что-то вроде calc(1px / 0)
и получить то же значение, что и calc(infinity * 1px)
.
Полезно знать, но я бы всё равно использовал infinity
напрямую, чтобы сделать CSS более очевидным.
Существует также константа -infinity
, дающая наименьшее возможное значение. Ничего удивительного, это то же самое, что умножить infinity
на -1
.
Конец
Итак, главное, что нужно знать о infinity
в CSS, — то, что она, по сути, является сокращением для обозначения наибольшего возможного значения в конкретной ситуации. Это значение может и будет меняться в зависимости от браузера, операционной системы и свойств CSS.
Использовать infinity
или нет — решать вам. Поддержка браузерами довольно хороша (на момент перевода статьи 91.87%), и infinity
может быть хорошим индикатором намерений, делающим CSS более читабельным, но это, конечно, необязательно.