Почему `overflow:hidden` препятствует работе`position:sticky`?
В следующем фрагменте есть липкий div
расположенный внутри контейнера. Он прилипает к верхней части панели прокрутки, оставаясь внутри своего контейнера все время. Это то же поведение, что и у UITableView
заголовки на iOS, где заголовки остаются видимыми, пока следующий заголовок не будет наверху.
Во втором фрагменте все то же самое, за исключением того, что контейнер имеет overflow:hidden
Правило CSS. Это, кажется, мешает position:sticky
поведение от работы правильно.
.parent {
position: relative;
background: #ccc;
width: 500px;
height: 150px;
overflow: auto;
margin-bottom: 20px;
}
.hidden-overflow {
overflow: hidden;
}
.sticky {
position: sticky;
background: #333;
text-align: center;
color: #fff;
top: 10px;
}
<div class="parent">
<div>
<div class="sticky">
Hi, I am a sticky inside the container which contains the first paragraph.
</div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus volutpat sed metus et porttitor. Integer bibendum lacus eget massa ultricies fermentum. Donec cursus magna eu congue posuere. Sed eget ligula quam. Sed laoreet enim sapien, eget volutpat nisl pellentesque vel. Nulla id dolor sed dolor sodales tristique. Curabitur feugiat massa sed massa bibendum semper et ac orci. In imperdiet nibh quis iaculis viverra. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque vestibulum, nunc non volutpat tristique, nisl nisi volutpat nibh, quis pulvinar purus ex nec justo. Sed a cursus turpis. Quisque nulla odio, lacinia quis vestibulum sit amet, elementum laoreet nisi. Etiam aliquet ligula sagittis,
consectetur ipsum sit amet, sodales augue.
</p>
</div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus volutpat sed metus et porttitor. Integer bibendum lacus eget massa ultricies fermentum. Donec cursus magna eu congue posuere. Sed eget ligula quam. Sed laoreet enim sapien, eget volutpat
nisl pellentesque vel. Nulla id dolor sed dolor sodales tristique. Curabitur feugiat massa sed massa bibendum semper et ac orci. In imperdiet nibh quis iaculis viverra. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos
himenaeos. Quisque vestibulum, nunc non volutpat tristique, nisl nisi volutpat nibh, quis pulvinar purus ex nec justo. Sed a cursus turpis. Quisque nulla odio, lacinia quis vestibulum sit amet, elementum laoreet nisi. Etiam aliquet ligula sagittis,
consectetur ipsum sit amet, sodales augue.
</p>
<p>
Integer congue augue a quam tincidunt, vitae dictum sem iaculis. Proin feugiat nibh vitae leo facilisis, eget laoreet augue dictum. Nunc facilisis tempor feugiat. Aenean eget interdum diam. Maecenas non risus iaculis, scelerisque ipsum eu, facilisis urna.
Integer velit justo, vestibulum vel vulputate vel, bibendum eu lorem. Phasellus viverra nisl a mi pretium eleifend.
</p>
</div>
<div class="parent">
<div class="hidden-overflow">
<div class="sticky">
Hi, I am another sticky in the container which contains the first paragraph, but my container has overflow:hidden.
</div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus volutpat sed metus et porttitor. Integer bibendum lacus eget massa ultricies fermentum. Donec cursus magna eu congue posuere. Sed eget ligula quam. Sed laoreet enim sapien, eget volutpat nisl pellentesque vel. Nulla id dolor sed dolor sodales tristique. Curabitur feugiat massa sed massa bibendum semper et ac orci. In imperdiet nibh quis iaculis viverra. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque vestibulum, nunc non volutpat tristique, nisl nisi volutpat nibh, quis pulvinar purus ex nec justo. Sed a cursus turpis. Quisque nulla odio, lacinia quis vestibulum sit amet, elementum laoreet nisi. Etiam aliquet ligula sagittis,
consectetur ipsum sit amet, sodales augue.
</p>
</div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus volutpat sed metus et porttitor. Integer bibendum lacus eget massa ultricies fermentum. Donec cursus magna eu congue posuere. Sed eget ligula quam. Sed laoreet enim sapien, eget volutpat
nisl pellentesque vel. Nulla id dolor sed dolor sodales tristique. Curabitur feugiat massa sed massa bibendum semper et ac orci. In imperdiet nibh quis iaculis viverra. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos
himenaeos. Quisque vestibulum, nunc non volutpat tristique, nisl nisi volutpat nibh, quis pulvinar purus ex nec justo. Sed a cursus turpis. Quisque nulla odio, lacinia quis vestibulum sit amet, elementum laoreet nisi. Etiam aliquet ligula sagittis,
consectetur ipsum sit amet, sodales augue.
</p>
<p>
Integer congue augue a quam tincidunt, vitae dictum sem iaculis. Proin feugiat nibh vitae leo facilisis, eget laoreet augue dictum. Nunc facilisis tempor feugiat. Aenean eget interdum diam. Maecenas non risus iaculis, scelerisque ipsum eu, facilisis urna.
Integer velit justo, vestibulum vel vulputate vel, bibendum eu lorem. Phasellus viverra nisl a mi pretium eleifend.
</p>
</div>
(Фрагмент адаптирован из @Daniel's здесь)
Почему не position:sticky
работать в контейнере с overflow:hidden
?
8 ответов
Прошло несколько лет с тех пор, как этот вопрос был первоначально опубликован, теперь есть еще один способ скрыть переполняющий контент:
contains: paint;
overflow: hidden
не мешает position: sticky
с работы. Но если вы установите overflow
в hidden
на любом предке вашего липкого элемента, этот элемент предка будет контейнером прокрутки для вашего липкого элемента. Если вы переключите overflow
значение вашего предка от hidden
в scroll
и прокрутите этого предка (не окна), тогда вы увидите, что sticky все еще работает.
Смотрите также https://github.com/wilddeer/stickyfill:
Любое значение по умолчанию (не видимое) для переполнения, переполнения-x или переполнения-y на любом из элементов предшествующего уровня привязывает привязку к контексту переполнения этого предшественника. Проще говоря, прокрутка предшественника приведет к залипанию липкого, прокрутка окна - нет. Это ожидается с переполнением: авто и переполнением: прокрутка, но часто вызывает проблемы и путаницу с переполнением: скрыто.
Или http://www.coreyford.name/files/position-sticky-presentation/:
Положение блока зависит от содержащего его блока (установленного как для position:static), а также от контейнера прокрутки, определенного ближайшим предком в том же документе с вычисленным значением для "overflow-x" или "overflow-y", отличным от 'visible' или окно просмотра, если такого предка не существует.
Или модуль позиционированного макета CSS Уровень 3 W3C Рабочий проект:
Склейко расположенное поле позиционируется аналогично относительно позиционированному блоку, но смещение вычисляется со ссылкой на ближайшего предка с ползунком прокрутки или в окне просмотра, если ни у какого предка нет прокручиваемого блока.
Я столкнулся с этой проблемой и нашел альтернативное решение, чтобы использовать вместоoverflow: hidden
. Насколько я могу судить, они работают почти одинаково, за исключением того, что точка привязки липкого элемента не изменяется при использованииclip
. Единственная проблема заключается в том, что по состоянию на ноябрь 2022 г.overflow: clip
имеет ограниченную (~80%) поддержку браузера: https://caniuse.com/mdn-css_properties_overflow_clip
Я не уверен, что это будет работать во всех случаях, но я столкнулся с этим и смог обойти проблему, заменив overflow: hidden;
с клип-путями.
.parent {
/*overflow: hidden; removed */
position: absolute; /*this is required for clip-paths to work*/
-webkit-clip-path: inset(0); /* safari*/
clip-path: inset(0);
clip: rect(0px, auto, auto, 0px); /* IE11/Edge (not that IE11 supports sticky anyway!) */
}
Поскольку необходимо добавить абсолютную позицию, оборачиваем элемент overflow: hidden в другую позицию: относительный элемент, а затем добавляем top, bottom, left и right: 0; должен заполнить его родительский контейнер.
С введением display: contents
Вы можете использовать sticky внутри контейнера с переполнением auto / hidden и пропустить это скучное ограничение.
Вам просто нужно обернуть ваш компонент в div с display: contents
Демонстрация: https://jsbin.com/zodacapamu/edit?html,css,output
Подробнее о https://css-tricks.com/get-ready-for-display-contents/
Конечно, не будет работать в IE11, пока кто-то не работает, но новые браузеры работают нормально.
На изображении ниже мы реализовали таблицу с около 50 столбцами с позицией "липкая" в заголовке и первыми 3 столбцами, и она работает.
position: sticky
до сих пор считается экспериментальной функцией, только с частичной поддержкой браузера.
В сафари position: sticky
требует webkit
префикс продавца:
position: -webkit-sticky;
Также обратите внимание, что position: sticky
ведет себя ошибочно внутри отмеченных родителей overflow: hidden
,
Более подробная информация доступна в этом выпуске Firefox.
Решение 2020:
У меня была такая же проблема и overflow-x: hidden
к счастью, можно заменить аналогичными свойствами.
В моем случае я хотел предотвратить горизонтальную прокрутку в мобильном окне просмотра. Поскольку я в основном использую сетку CSS, я решил это с помощью SASS / SCSS:
@include media('<tablet') { // When tablet viewport or smaller
main {
display: grid;
grid-template-columns: 1fr;
justify-items: center;
...
Это предотвращает попадание любого элемента внутри <main>
тег будет переполнен.
Кстати, для поддержки кроссбраузера CSS-сетки вы можете просто использовать автопрефиксер.
По словам Mozilla ( ссылка здесь)
Sticky является экспериментальным API и не должен использоваться в производственном коде.
Так что для меня только это является причиной, почему это не работает. И Edge, и IE 11 тоже не поддерживают его, поэтому для меня проделать что-то подобное с javascript было бы далеко вперед, есть много чего, что должно помочь.
Примером этого здесь
Надеюсь это поможет.