Почему "переполнение: скрыто" предотвращает "положение: липкое" от работы?

В следующем фрагменте есть липкий div, расположенный внутри контейнера. Он прилипает к верхней части панели прокрутки, постоянно находясь в контейнере. Это то же поведение, что и заголовки UITableView на iOS, где заголовки остаются видимыми до тех пор, пока следующий заголовок не окажется наверху.

Во втором фрагменте все одно и то же, за исключением того, что контейнер имеет правило CSS overflow:hidden. Это, по-видимому, предотвращает правильную работу 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>

Ответ 1

overflow: hidden не препятствует работе position: sticky. Но если вы установите overflow на hidden для любого предка вашего липкого элемента, то этот элемент-предок будет прокручивающим контейнером для вашего липкого элемента. Если вы переключите значение overflow на своего предка от hidden до scroll и прокрутите этот предок (а не окно), вы увидите, что липкий файл все еще работает.

См. также https://github.com/wilddeer/stickyfill#pro-tips:

Любое значение по умолчанию (не отображается) для переполнения, переполнения-x или overflow-y для любого из элементов предшественника привязывает клеймо контекст переполнения этого предшественника. Проще говоря, прокрутка предшественник заставит липкую придерживаться, прокручивая окно не будет. Это ожидается при переполнении: автоматическое и переполнение: прокрутка, но часто вызывает проблемы и путаницу с переполнением: скрытый.

Или http://www.coreyford.name/files/position-sticky-presentation/:

Позиция блока зависит от его содержащего блока (устанавливается как для position: static), а также его прокручивающий контейнер, определенный ближайшего предка в том же документе с вычисленным значением для 'overflow-x' или 'overflow-y', кроме "visible", или viewport if такого предка не существует.

Или CSS-позиционированный модуль макета 3-го уровня Рабочий проект W3C:

Липко расположенная коробка расположена аналогично относительно, но смещение вычисляется со ссылкой на ближайшего предка с прокручиваемым ящиком или видового экрана, если нет предка имеет прокрутку.

Ответ 2

Я не уверен, что это будет работать во всех случаях, но я столкнулся с этим и смог обойти проблему, заменив 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; должен заполнить его родительским контейнером.

Ответ 3

position: sticky по-прежнему считается экспериментальной функцией, только частичная поддержка браузера.

В Safari для position: sticky требуется префикс поставщика webkit:

position: -webkit-sticky;

Кроме того, обратите внимание, что position: sticky ведет себя хаотично внутри родителей с пометкой overflow: hidden.

Дополнительная информация доступна в этом Firefox Issue.

Ответ 4

В соответствии с Mozilla (ссылка здесь)

Sticky - экспериментальный API и не должен использоваться в производственном коде.

Итак, для меня это только причина, почему она не работает. И Edge, и IE 11 не поддерживают его ни для меня, так что делать что-то подобное с javascript было бы в будущем, есть много, что должно помочь.

Примером является здесь

Надеюсь, что это поможет.