3

I'm having trouble getting a footer to stick to the bottom of a scrollable block element. It only works if the content (table in this case) is greater than the container height. How do I always get the the footer to stick to the bottom?

I tried using position: absolute instead, but that stays fixed when the user scrolls.

.container {
  position: relative;
  overflow-y: scroll;
  height: 150px;
  display: block;
  border: solid 1px black;
}

.footer {
  position: sticky;
  right: 0;
  bottom: 0;
  float: right;
  background-color: lightblue;
}
<div class="container">
  <table>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
  </table>
  <div class="footer">Footer</div>
</div>
<br/>
<div class="container">
  <table>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
  </table>
  <div class="footer">Footer</div>
</div>
Stephen Collins
  • 426
  • 5
  • 15
  • Will the table always have a fixed height of 150px? Or will it be variable? – evilgenious448 Sep 18 '20 at 17:26
  • Please add the code from your JSFiddle directly into the question - you can create a runnable Stack Snippet using the `[<>]` button on the question toolbar to do this. External links are discouraged here as they can change or break over time, making your question unhelpful to future users if they can't see the code :) – FluffyKitten Sep 18 '20 at 17:43
  • @evilgenious448 I suppose max-height could be used instead to solve the issue, but the height needs to be fixed. – Stephen Collins Sep 18 '20 at 17:52
  • 1
    @FluffyKitten Done :) – Stephen Collins Sep 18 '20 at 17:52

2 Answers2

5

You need to change the display of the .container to flex

display: flex;
flex-direction: column;

And the .footer needs to have a margin-top: auto;

See code here:

.container {
  position: relative;
  overflow-y: scroll;
  height: 150px;
  border: solid 1px black;
  display: flex;
  flex-direction: column;
}

.footer {
  position: sticky;
  right: 0;
  bottom: 0;
  float: right;
  background-color: lightblue;
  margin-top: auto;
}
<div class="container">
  <table>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
  </table>
  <div class="footer">Footer</div>
</div>
<br/>
<div class="container">
  <table>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
  </table>
  <div class="footer">Footer</div>
</div>

In this example the footer takes up the entire width of the container, however that is easy to fix in the styling if you need to.

evilgenious448
  • 518
  • 2
  • 11
0

For your purpose you can use a flex-box in combination with a scrollable content element. Using flex-direction: column; justify-content: space-between; the last child of the content element will always be positioned at the bottom.

Edit: I assumed that you want to have a fixed content height. But this also works with dynamic heights. For this you have to change the height: 150px; property to max-height property.

.container {
  position: relative;
  overflow-y: scroll;
  border: solid 1px black;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  margin-bottom: 16px;
}

.content{
  position: relative;
  width: 100%;
  height: 150px;
  background: red;
  overflow-y: auto;
}

.content__item{
  position: relative;
  width: 100%;
  padding: 8px;
  box-sizing: border-box;
  color: #fff;
  font-size: 24px;
}

.footer {
  position: relative;
  width: 100%;
  background: green;
  color: #fff;
}
<div class="container">
   <div class="content">
   <table>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
        <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
   </table>
   </div>
   <div class="footer">Footer</div>
</div>

<div class="container">
   <div class="content">
   <table>
    <tr><td>Hello</td></tr>
    <tr><td>Hello</td></tr>
   </table>
   </div>
   <div class="footer">Footer</div>
</div>
michaelT
  • 1,533
  • 12
  • 41