1

I have a somewhat complex HTML document that contains different elements with position: sticky. These elements are on different levels in the hierarchy: there are several sticky sidebars, several headers where the lower header "pushes away" the upper header when the user scrolls up, etc.

With some of these elements, position: sticky works okay, but other elements behave like position: relative. There seems to be some connection to the hierarchy level and to the parent elements: on some levels, position: sticky works okay, on other levels (or inside certain parent elements), it doesn't work. I'm currently not able to see a pattern, and changing some CSS properties (trial-and-error) did not help.

Before I go on with trial-and-error, it could help to know which CSS properties (of the element or its ancestors) are able to prevent position:sticky from working. In other words, which conditions have to be satisfied for position:sticky?

Jonas Sourlier
  • 13,684
  • 16
  • 77
  • 148
  • I hope you are aware it is not fully implemented. IE does not support the 'sticky': http://caniuse.com/#feat=css-sticky – Daniel Apr 28 '17 at 21:34
  • @Daniel yes, I'm talking about the spec. I'd like to know what rules there are that prevent it from working. Rules like "if the element has an absolutely positioned ancestor, then position:sticky has the same effect as position:relative". – Jonas Sourlier Apr 29 '17 at 10:03

3 Answers3

3

I think I discovered the reason: if an element is contained in another element which has overflow:hidden, then position:sticky is ignored.

See the following snippet, which I adapted from @Daniel's:

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

However I'm not sure about the reason for this behaviour. The container with overflow:hidden is itself a child of the scrolling container, so it does not prevent the scrolling. I'm not sure why such an element can't be sticky.

Jonas Sourlier
  • 13,684
  • 16
  • 77
  • 148
  • 1
    The box you put your sticky in has the standard property static, which is basically equal to relative. The W3C does say that the sticky will take its parent as reference. So with the parent stuck in the document flow with a static property, the sticky acts as expected. – Daniel Apr 30 '17 at 16:45
  • @Daniel You're right, my example does not depend on `overflow:hidden`. But I'm also sure that it's possible to make a sticky div inside a container with `position: static`. So a container with `position:static` does not mean the div cannot be sticky relative to a conatiner higher up in the hierarchy. Gonna update my code snippet as soon as I have found out how. – Jonas Sourlier Apr 30 '17 at 18:46
  • @Daniel I updated the snippet to show what I mean. As you can see, both sticky divs are in a container that wraps the first paragraph. However, if this container has `overflow: hidden`, then its child does not behave sticky. Any idea why? – Jonas Sourlier May 10 '17 at 13:52
  • Actually it is not ignored, but the offset is now computed to your element with `overflow: hidden` and no longer to the window. Change the `overflow` value to `scroll` to see that it's still sticky or see my answer to your question here: https://stackoverflow.com/a/44929597/1384441 – chaenu Jul 05 '17 at 14:54
1

I have no knowledge of sticky, so my findings are based on playing with it. Hope it will help you. I find in the eaxample that if sticky does not have a top rule in the CSS, it behaves like a relative. Is that what you refer to?

.parent {
  position: relative;
  background: #ccc;
  width: 500px;
  height: 150px;
  overflow: auto;
  margin-bottom: 20px;
}

.sticky1 {
  position: sticky;
  background: #333;
  text-align: center;
  color: #fff;
}

.sticky2 {
  position: sticky;
  background: #333;
  text-align: center;
  color: #fff;
  top: 10px;
}
<div class="parent">

  <div class="sticky1">
    Hi, I am sticky1 without a top
  </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="sticky2">
    Hi, I am sticky2 with a top
  </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
  • 4,816
  • 3
  • 27
  • 31
  • Thank you. Yes this is one of these rules I'd like to hear about. Unfortunately, there must be more of them, because the elements on my page that don't behave sticky are `top:20px`. – Jonas Sourlier Apr 29 '17 at 20:18
0

I just notice (in chrome) that parent display: block prevent child from being sticky. display: inline fixed this.