1

This is an issue that I've run into on multiple occasions and figured this time I would try and seek a definitive answer. What I'm trying to do, is center an element vertically while having another element act as a "footer" and snapping to the bottom of the same container. Like so:

enter image description here

The problem is that the footer will have a dynamic height. The expected behavior is that if there's enough space, the middle element will stay centered vertically; if the footer becomes too large for that to happen, the centered content will shift upwards making room for the footer.

The closest solution I've found is in this question. But like every other solution I've seen, it requires knowing the height of the footer.

I have a hunch that this is impossible to do with flexbox. The solution I end up always falling back to is the classic position: relative wrapper with position: absolute on the footer.

Here's a demo fiddle if you'd like to see where I left off on my last attempt.

flex-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  border: 4px solid blue;
  height: 300px;
  width: 300px;
}

flex-container>flex-spacer {
  margin-top: auto;
  visibility: hidden;
}

flex-container>flex-item {
  display: flex;
}

flex-container>flex-footer {
  margin-top: auto;
  margin-bottom: auto;
}

flex-container>flex-spacer,
flex-container>flex-footer {
  border: 4px solid chartreuse;
}

flex-container>flex-item>flex-item {
  border: 4px solid aqua;
  height: 50px;
  width: 50px;
  margin: 0 5px;
}
<flex-container>
  <flex-spacer></flex-spacer>
  <flex-item>
    <flex-item></flex-item>
    <flex-item></flex-item>
    <flex-item></flex-item>
  </flex-item>
  <flex-footer>
    this is the footer element<br /> this is the footer element<br />
  </flex-footer>
</flex-container>
divibisan
  • 11,659
  • 11
  • 40
  • 58
garetmckinley
  • 1,122
  • 2
  • 11
  • 29

1 Answers1

0

What you needed was one flexbox for the whole container, and a nested flexbox for the content itself. This allows you to apply two different alignment rules while maintaining the 'flexibility' that flexboxes are known for.

A few of your other elements - such as the 'spacer' - were unnecessary.

flex-container {
    display: flex;
    flex-direction:column;
    align-items: center;
    justify-content:flex-end;
    border: 4px solid blue;
    height: 300px;
    width: 300px;
}

flex-container > flex-center-content {
    display:flex;
    height:100%;
    width:100%;
    align-items:center;
    justify-content:center;
}

flex-container > flex-footer {
    border: 4px solid chartreuse;
}

flex-container > flex-center-content > flex-item {
    border: 4px solid aqua;
    height: 50px;
    width: 50px;
    margin: 0 5px;
}
<flex-container>
  <flex-center-content>
   <flex-item></flex-item>
   <flex-item></flex-item>
   <flex-item></flex-item>
  </flex-center-content>
    <flex-footer>
      this is the footer element<br />
      this is the footer element<br />
      this is footeeeeer<br>
      look how tall I am<br>
      and how much I push things<br>
    </flex-footer>
</flex-container>

FIDDLE

Joel Rummel
  • 802
  • 5
  • 18
  • This does not satisfy the requirements of my question. The blue squares in your example *never* center themselves vertically (see my screenshot in the question), even when there is plenty of room to be centered within the container. – garetmckinley Aug 23 '18 at 20:23
  • @garetmckinley The blue squares center themselves with the footer behaving as the bottom border of the container, which is what I thought you were asking for. If you want the blue boxes to ignore the footer entirely until the footer takes up about half the height of the container... well then you've got a whole different problem that isn't really meant for flexbox, and quite frankly I'm not sure why you'd ever want to accomplish that. – Joel Rummel Aug 24 '18 at 16:07
  • `and quite frankly I'm not sure why you'd ever want to accomplish that` there are countless reasons why you'd want to accomplish that. You could apply the same concept but horizontally, which is something more frequently used. Think of a app title bar. The title text should absolute center itself with buttons on both the right and left side, however when there's not enough room in the title bar, the buttons will shift the centered text. – garetmckinley Aug 25 '18 at 01:50
  • Regardless, I clearly mentioned the expected behavior in the original question `The expected behavior is that if there's enough space, the middle element will stay centered vertically; if the footer becomes too large for that to happen, the centered content will shift upwards making room for the footer.` along with saying that I'm not sure if it's possible without using absolute positioning. There are multiple reasons why absolute positioning is a bad idea in this context though, first and foremost because of possible content overlap. – garetmckinley Aug 25 '18 at 01:52