1

I need to have a vertical parent-height div which contains smaller divs. In case there's extra space, all but the last divs should be placed on top, and the latest div should be placed at the bottom. I've implemented it with Bootstrap and flex.

Now I thought that it would be nice if, when possible, the bottom div will be at the bottom of the viewport instead of at the bottom of the containing div. I've implemented it with position: sticky, and it works on Chrome but not in Firefox (both should support position: sticky).

My code:

<div id="container" class="d-flex flex-column">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    <div class="d-flex flex-column last">
      <div class="flex-item mt-auto last-inner">3</div>
    </div>
</div>

CSS:

#container {
    height: 1000px;
}

#container .last {
    flex: 1;
}

#container .last-inner {
    position: sticky;
    bottom: 0;
}

JSFiddle

Paul
  • 6,061
  • 6
  • 39
  • 70
  • 1
    Turns out it's a Firefox regression: https://bugzilla.mozilla.org/show_bug.cgi?id=1488080 – Paul Sep 02 '18 at 19:41

1 Answers1

3

sticky seems to be tricky and not yet implemented the same way everywhere.

I usually trust FF on this behavior, chrome add issues with sticky and removed it a couple of times the past 3 years, i'm glad it is avalaible again and for month in chrome.

For FF, the sticky element has to be a direct child of #container, else, it will stick at bottom 0 of .last being a flex child. being a flex child, it becomes the first parent reference for the coordonate bottom:0 instead body. #container has obviously no formatting context and html can be the reference.

#container {
  height: 1000px;
}

#container .last {
  flex: 1;
}

#container .last-inner {
  position: sticky;
  bottom: 0;
}

.flex-item {
  background: tomato;
  padding: 5px;
  width: 200px;
  height: 50px;
  margin-top: 10px;
  line-height: 50px;
  color: white;
  font-weight: bold;
  font-size: 2em;
  text-align: center;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<div id="container" class="d-flex flex-column">
  <div class="flex-item">1</div>
  <div class="flex-item">2</div>
  <div class="d-flex flex-column last">
  </div>
  <div class="flex-item mt-auto last-inner">3</div>
</div>
G-Cyrillus
  • 101,410
  • 14
  • 105
  • 129
  • 1
    Now works in Chrome, FF and Edge. Helpful explanation. Thanks. – Michael Benjamin Sep 02 '18 at 13:55
  • Thanks, but this suffers from another problem - if the container is not high enough, 2 and 3 overlap. I'd like the container to extend in this case, as if `sticky` is not used – Paul Sep 02 '18 at 14:11
  • @Paul the container in the demo is a 1000px of height, and you want a sticky element, at the bottom. extending the container won't help. You can also set a top value, so it will move down if the window is too small. but i do not see how that helps unless it is updated via a javascript checking if the last element and the sticky one are overlapping to update the top value. here is the idea about top http://jsfiddle.net/1p4gtruk/64/ . this a value to update via js to be coherent with the content before it , when needed. it deserve here a js question/script to be solved – G-Cyrillus Sep 02 '18 at 14:25
  • @G-Cyr I didn't write what I mean clearly, sorry. I meant that if the viewport (not the container) is too small, with my example (on Chrome) 3 turns out below 2. In this example, they are overlapped, and that doesn't work for me. – Paul Sep 02 '18 at 14:28
  • @Paul , okay, i did understand the issue . it is not pushed down . it behaves the same in FF – G-Cyrillus Sep 02 '18 at 14:29