web-dev-qa-db-fra.com

Pourquoi `overflow: hidden` empêche-t-il` `position: sticky` de fonctionner?

Dans l'extrait suivant, il y a un sticky div positionné à l'intérieur d'un conteneur. Il colle au haut du panneau défilant tout en restant à l'intérieur de son conteneur tout le temps. Ce comportement est identique à celui des en-têtes UITableView sous iOS, dans lesquels les en-têtes restent visibles jusqu'à ce que l'en-tête suivant apparaisse en haut.

Dans le deuxième extrait, tout est identique sauf que le conteneur a un overflow:hidden Règle CSS. Cela semble empêcher le position:sticky comportement de fonctionner correctement.

.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>

(Extrait adapté de @ Daniel's ici )

Pourquoi ne pas position:sticky travailler dans un conteneur avec overflow:hidden?

35
cheeesus

overflow: hidden n'empêche pas position: sticky de travailler. Mais si vous définissez overflow sur hidden sur un ancêtre de votre élément collant, cet élément ancêtre sera le conteneur de défilement de votre élément collant. Si vous faites passer la valeur overflow de votre ancêtre de hidden à scroll et faites défiler cet ancêtre (pas la fenêtre), vous constaterez que sticky fonctionne toujours.

Voir aussi https://github.com/wilddeer/stickyfill#pro-tips :

Toute valeur non visible par défaut (non visible) de dépassement de capacité, de dépassement de capacité-x ou de dépassement de capacité-y sur l'un des éléments prédécesseurs ancre l'élément collant dans le contexte de dépassement de capacité de ce prédécesseur. En parlant simplement, si vous faites défiler le prédécesseur, le problème persiste, mais pas dans la fenêtre. Ceci est attendu avec overflow: auto et overflow: scroll, mais provoque souvent des problèmes et de la confusion avec overflow: hidden.

Ou http://www.coreyford.name/files/position-sticky-presentation/ :

La position de la boîte dépend de son bloc conteneur (établi comme pour position: static) ainsi que de son conteneur de défilement , défini par l'ancêtre le plus proche dans le même document avec une valeur calculée pour 'overflow-x' ou 'overflow-y' autre que 'visible', ou la fenêtre d'affichage si aucun tel ancêtre n'existe.

Ou le brouillon de travail du module de disposition positionné par CSS du niveau 3 du W3C :

Une case collée est positionnée de la même manière qu'une case relativement positionnée, mais le décalage est calculé en référence à l'ancêtre le plus proche avec une case de défilement ou à la fenêtre d'affichage si aucun ancêtre n'a de case de défilement.

40
chaenu

Je ne suis pas sûr que cela fonctionnera dans tous les cas, mais je me suis heurté à cela et j'ai pu contourner le problème en remplaçant overflow: hidden; Par clips-path .

.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!) */
}

En ce qui concerne l'ajout de la position absolue, encapsulez l'élément de débordement: élément masqué dans une autre position: élément relatif, puis ajoutez les éléments haut, bas, gauche et droite: 0; devrait lui faire remplir son conteneur parent.

3
marmite

Avec l'introduction de display: contents, vous pouvez utiliser sticky dans un conteneur à débordement auto/hidden et ignorer cette limitation fastidieuse.

Vous devez juste envelopper votre composant dans une div avec display: contents

Démo: https://jsbin.com/zodacapamu/edit?html,css,output

En savoir plus sur https://css-tricks.com/get-ready-for-display-contents/

Bien sûr, cela ne fonctionnera pas dans IE11 avant que quelqu'un ne fonctionne, mais les nouveaux navigateurs fonctionnent bien.

Dans l'image ci-dessous, nous avons mis en place un tableau d'environ 50 colonnes avec la position collante dans l'en-tête et les 3 premières colonnes.

démo

0
Rafael Motta