CPU-хак для CSS



Рубрика «Ненормальное программирование».



Задача: сделать так, чтобы значение CSS-переменной самостоятельно увеличивалось от собственного значения по какому-то сигналу. Что-то вроде --my-var: calc(var(--my-var) + 1);. В императивных языках же есть i++, подавайте-ка его сюда и в декларативные языки, будьте любезны.



Разумеется, прямо так сделать нельзя, иначе бы получались циклические зависимости, из-за которых невозможно отрисовать кадр. CSS-движок в том числе проверит, чтобы у вас не было обращения переменной к самой себе через другие переменные. Так в спеке написано.



Но... Джейн Ори делится интересным хаком, который позволяет всё-таки обойти это ограничение. Для хака нужно знать три вещи:

1. Анимация имеет высокий приоритет в каскаде. Свойство, которое меняется анимацией, никакой специфичностью не перебить.

2. У анимаций есть кэш. Чтобы не считать значения свойств внутри анимаций по кругу, они жёстко кэшируются, даже если внутри идёт обращение к var(--my-var), которая где-то снаружи меняется.

3. Кэш анимации сбрасывается, если изменить сами свойства, касающиеся настроек анимации, вроде animation-play-state или animation-duration.



А дальше нужно хитрым образом переключать «кадры» так, чтобы кэш то сбрасывался, то включался. Коротко объяснить не смогу, смотрите демки в статье, с ними становится понятнее. Работает вся магия по ховеру, потому что для запуска заклинания без JavaScript всё-таки нужно из мира HTML прокинуть каким-то образом сигнал для старта в CSS.



Почему это называется CPU-хаком? Потому что по сути у вас появляется простой вычислительный юнит в CSS, настоящий счётчик, который можно менять под свои нужды. Так Джейн Ори делится демками, где она на чистом CSS подбирает позицию курсора во вьюпорте (причём бинарным поиском, чтобы быстрее было), запускает игру «Жизнь» Конвея, а потом всё это комбинирует в полноценный Арканоид.



Зачем это уметь? Ведь на JS объективно понятнее, производительнее и правильнее такое делать.

- Во-первых, я пока разбирался в демках, сломал мозг, но немного прозрел. Мне просто нравится разбираться в таких нюансах. Знание — сила.

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

- В-третьих, скажите потом ещё, что CSS — не язык программирования.



https://dev.to/janeori/expert-css-the-cpu-hack-4ddj