Search code examples
cssflexboxcss-positionsticky

My position: sticky element isn't sticky when using flexbox


I was stuck on this for a little bit and thought I'd share this position: sticky + flexbox gotcha:

My sticky div was working fine until I switched my view to a flex box container, and suddenly the div wasn't sticky when it was wrapped in a flexbox parent.

.flexbox-wrapper {
  display: flex;
  height: 600px;
}
.regular {
  background-color: blue;
}
.sticky {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  background-color: red;
}
<div class="flexbox-wrapper">
  <div class="regular">
    This is the regular box
  </div>
  <div class="sticky">
    This is the sticky box
  </div>
</div>

JSFiddle showing the problem


Solution

  • Since flex box elements default to stretch, all the elements are the same height, which can't be scrolled against.

    Adding align-self: flex-start to the sticky element set the height to auto, which allowed scrolling, and fixed it.

    Currently this is supported in all major browsers, but Safari is still behind a -webkit- prefix, and other browsers except for Firefox have some issues with position: sticky tables.

    .flexbox-wrapper {
      display: flex;
      overflow: auto;
      height: 200px;          /* Not necessary -- for example only */
    }
    .regular {
      background-color: blue; /* Not necessary -- for example only */
      height: 600px;          /* Not necessary -- for example only */
    }
    .sticky {
      position: -webkit-sticky; /* for Safari */
      position: sticky;
      top: 0;
      align-self: flex-start; /* <-- this is the fix */
      background-color: red;  /* Not necessary -- for example only */
    }
    <div class="flexbox-wrapper">
      <div class="regular">
        This is the regular box
      </div>
      <div class="sticky">
        This is the sticky box
      </div>
    </div>

    JSFiddle showing the solution