На работе в очередной раз потребовалось на сайте одного проекта реализовать фичу, связанной с появлением блока во вьюпорте, т.е. кое-что в дизайне должно меняться, когда блок виден на экране. Блок должен был как бы раскрываться по ширине, когда входил во вьюпорт. Обычно это реализуется через Intersection Observer, т.е. через джаваскрипт. Но я засомневался, потому что в CSS постоянно что-то новое добавляется, я просто не успеваю следить, полез гуглить, вдруг пропустил что-то новое.
Так вот, такой функционал никогда не будет добавлен в CSS. И различный другой запрашиваемый людьми функционал тоже не будет добавлен. 🙂 Оказывается, существует "Рабочая группа по CSS" (CSS Working Group) для решения проблем CSS. У них есть сайт с FAQ: https://wiki.csswg.org/faq - там есть как раз пункт "Selectors that Depend on Layout", т.е. селекторы, которые зависят от текущего layout Цитата из FAQ:
И их ответ:
Короче, в группу постоянно приходят от разработчиков запросы на добавлении селектора, выбирающего, когда контент вылазит наружу, или на селектор, что стики-элемент уперся в край, или вот на нужный мне селектор нахождения во вьюпорте. Ну и всякое такое в этом роде. И рабочая группа отвергает такие запросы. Главная причина этих отказов - это высокая вероятность бесконечного цикла, когда браузер будет перерисовывать разные состояния, потому что они будут менять друг друга. Например: элемент появился во вьюпорте - соседний элемент уменьшился по высоте и элемент... пропадает из вьюпорта! А у такого состояния срабатывает другой стиль, который удлиняет по высоте соседний вышестоящий элемент и наш элемент опять попадает во вьюпорт. И так происходит до бесконечности!
Но в CSS давным давно уже есть селектор, который может входить в бесконечный цикл - это селектор псевдокласса :hover. Я даже код придумал для этого безобразия:
Современные браузеры для :hover имеют встроенную защиту от бесконечной перерисовки layout. И если не двигать курсор мышки, то цикл перерисовки останавливается. Но я добавил transition и защита уже не работает! Блок бесконечно дергается, проверено на хроме и фф. Причем даже немного загружается графический процессор!
А теперь подумайте, что было бы при наличии какого-нибудь селектора :in-viewport? Можно было бы дико дергать дизайн вообще без действий пользователя. Отключение жса тут уже не поможет.
Поэтому остается нам фронтендерам юзать Intersection Observer и не жужжать. 😃
Так вот, такой функционал никогда не будет добавлен в CSS. И различный другой запрашиваемый людьми функционал тоже не будет добавлен. 🙂 Оказывается, существует "Рабочая группа по CSS" (CSS Working Group) для решения проблем CSS. У них есть сайт с FAQ: https://wiki.csswg.org/faq - там есть как раз пункт "Selectors that Depend on Layout", т.е. селекторы, которые зависят от текущего layout Цитата из FAQ:
I would like an :overflowing pseudo class to select elements which overflow
I would like a :stuck pseudo class to select elements with position:sticky which are currently stuck
I would like a :on-screen pseudo class to select elements which are currently in the viewport
I would like a :stuck pseudo class to select elements with position:sticky which are currently stuck
I would like a :on-screen pseudo class to select elements which are currently in the viewport
И их ответ:
Selectors in general, and pseudo classes in particular, cannot depend on layout, because otherwise they could be used to modify layout in a way that made them no longer match, which would modify the layout back to where it was, so they match again, and we get stuck in an infinite loop of contradictions.
Короче, в группу постоянно приходят от разработчиков запросы на добавлении селектора, выбирающего, когда контент вылазит наружу, или на селектор, что стики-элемент уперся в край, или вот на нужный мне селектор нахождения во вьюпорте. Ну и всякое такое в этом роде. И рабочая группа отвергает такие запросы. Главная причина этих отказов - это высокая вероятность бесконечного цикла, когда браузер будет перерисовывать разные состояния, потому что они будут менять друг друга. Например: элемент появился во вьюпорте - соседний элемент уменьшился по высоте и элемент... пропадает из вьюпорта! А у такого состояния срабатывает другой стиль, который удлиняет по высоте соседний вышестоящий элемент и наш элемент опять попадает во вьюпорт. И так происходит до бесконечности!
Но в CSS давным давно уже есть селектор, который может входить в бесконечный цикл - это селектор псевдокласса :hover. Я даже код придумал для этого безобразия:
<div class="funny-block"> </div>
.funny-block {
width: 200px;
height: 200px;
border: 1px solid black;
background-color: beige;
transition: all 0.5s ease; /* гарантированно добавляет бесконечное дёргание */
}
.funny-block:hover {
width: 100px;
height: 200px;
border: 1px solid black;
background-color: beige;
}
Современные браузеры для :hover имеют встроенную защиту от бесконечной перерисовки layout. И если не двигать курсор мышки, то цикл перерисовки останавливается. Но я добавил transition и защита уже не работает! Блок бесконечно дергается, проверено на хроме и фф. Причем даже немного загружается графический процессор!
А теперь подумайте, что было бы при наличии какого-нибудь селектора :in-viewport? Можно было бы дико дергать дизайн вообще без действий пользователя. Отключение жса тут уже не поможет.
Поэтому остается нам фронтендерам юзать Intersection Observer и не жужжать. 😃


