Alessandro
Alessandro

Reputation: 99

I don't manage to get an element sticking to the bottom using flexbox

I want to align two elements in such a way, that one sticks to the top, and one to the bottom of the viewport. I'm trying to achieve this with flexbox, but don't want to use absolute positioning.

Whatever I tried, didnt work: I found this question on stock overflow, and tried to implement those answers - yet I still can't achieve the wanted result. Can anybody point me in the right direction, or explain what I did wrong?

Below is my html / css, here you can find the code snippets on jsbin, with different stuff i tried.

All of the other stackoverflow questions I found regarding this topic didn't work for me either - I really don't get why. Any help would be really appreciated.

<html>
  <body>
    <div class="top">
      <p class="text">Top</p>
    </div>
    <div class="bottom">
      <p class="text">Bottom</p>
    </div>
  </body>
</html>
body {
  min-height: 100%;
  display: flex;
  flex-direction: column;
}

.top {
  flex-grow: 1;
}

.bottom {
  margin-top: auto;
}

Upvotes: 1

Views: 60

Answers (2)

Rene van der Lende
Rene van der Lende

Reputation: 5291

The CSS in the snippet contains a full explanation of what I did and why, so here just a summary:

  • min-height: 100% needs to be min-height: 100vh as with 100% body will only take up the summarized height of the direct child elements it contains.
  • Flexbox justify-content: space-between to move outermost child elements to either side of the flexbox container. With flex-direction: column that would be top and bottom of the container.
  • The above makes .top and .bottom CSS as-is obsolete.

Snippet

/* Demo, to better see space distribution */
* { outline: 1px dashed }

p {
    /* BEWARE: by default a <p> has 'margin: 1em 0'
               adding extra space above and below */
}

body {
    min-height: 100vh; /* from 100% */
    /* as 100% will make body only use up total height
       of elements it contains. 100vh will force it to
       fill the entire viewport height.
    */

    margin: 0; /* to remove HTML default 8px spacing */
    /* Margin adds to the total height of body
       causing the vertical scrollbar to appear
       when using 100vh */

    display: flex; flex-direction: column;

    /* moves two outer elements to either side */
    /* more elements get distributed inbetween */
    justify-content: space-between;
    /* I put in extra <div> between top and bottom
       to show what happens.
    */
}

.top {/* [OBSOLETE] */
    /* makes this element fill the entire screen */
/*    flex-grow: 1; /* probably unwanted, disabled */
}

.bottom {/* [OBSOLETE] */
/*    margin-top: auto; /* not required for effect */
    /* handled by flexbox parent justify property */
}

/*
    As body grows with content it can (and probably will)
    exceed 100vh, making .bottom move downward out of the 
    viewport. And when you scroll down, .top will move out
    of view.

    If you need either top/bottom permanently fixed you
    will have to use the position: fixed property
    on the elements instead of the Flexbox solution.

    - .top    { position: fixed; top: 0 }
    - .bottom { position: fixed; bottom: 0 }
*/
<div class="top">
    <p class="text">Top</p>
</div>

<div>
    <p>extra div &gt; p 1</p>
</div>

<div>
    <p>extra div &gt; p 2</p>
</div>

<div class="bottom">
    <p class="text">Bottom</p>
</div>

Upvotes: 2

Mushroomator
Mushroomator

Reputation: 9238

You could use CSS grid and just create 3 rows. Two with size of auto making the rows as big as they need to be and one of size 1fr meaning it takes the rest of the space. There is a great guide for CSS grid at CSS Tricks.

body {
  margin: 0px;
  padding: 0px;
  height: 100vh;
  /* CSS Grid */
  display: grid;
  /* 3 rows */
  grid-template-rows: auto 1fr auto; 
}

.bottom {
  background: red;
}

.top {
  background: red;
}
<body>
  <div class="top">
    <p class="text">Top</p>
  </div>
  <div>
    Content
  </div>
  <div class="bottom">
    <p class="text">Bottom</p>
  </div>
</body>

Upvotes: 2

Related Questions