51

I figured this would be simple, I need to align both of the inside divs (green and blue) to the bottom of their container (red). I'm hoping to not use absolute positioning and i need it to be ie6,7,8 ff chrome safari etc compatible.

<div style="border:1px solid red;">
    <div style="border:1px solid green; width:20px; height:20px; float:left;"></div>
    <div style="border:1px solid blue; width:20px; height:30px; float:left;"></div>
    <div style="clear:both;"></div>
</div>

i've tried using vertical-align but can't find a simple solution.

thanks for the help, p.

EDIT here's my attempt at abs pos solution:

<div style="border:1px solid red; position:relative;">
    <div style="border:1px solid green; width:20px; height:20px; float:left; position:absolute; bottom:0px;"></div>
    <div style="border:1px solid blue; width:20px; height:30px; float:left; position:absolute; bottom:0px;"></div>
    <div style="clear:both;"></div>
</div>
pstanton
  • 35,033
  • 24
  • 126
  • 168

7 Answers7

78

Why can't you use absolute positioning? Vertical-align does not work (except for tables). Make your container's position: relative. Then absolutely position the internal divs using bottom: 0; Should work like a charm.

EDIT By zoidberg (i will update the answer instead)

<div style="position:relative; border: 1px solid red;width: 40px; height: 40px;">
   <div style="border:1px solid green;position: absolute; bottom: 0; left: 0; width: 20px; height: 20px;"></div>
   <div style="border:1px solid blue;position: absolute; bottom: 0; left: 20px; width: 20px height: 20px;"></div>
</div>
Zoidberg
  • 10,137
  • 2
  • 31
  • 53
42

The modern way to do this is with flexbox, adding align-items: flex-end; on the container.

With this content:

<div class="Container">
  <div>one</div>
  <div>two</div>
</div>

Use this style:

.Container {
  display: flex;
  align-items: flex-end;
}

https://codepen.io/rds/pen/gGMBbg

rds
  • 26,253
  • 19
  • 107
  • 134
  • 4
    For me it worked using `flex-direction:column; justify-content:space-between;`. – joanlofe Nov 15 '17 at 15:01
  • 1
    This worked way better for me than absolute positioning which was giving some really odd side-effect behaviors when mingled with bootstrap. – Ben L. May 05 '18 at 23:04
  • @joanlofe that worked!, but don't forget `display:flex;` also in the container – Alcides May 01 '20 at 23:50
  • 1
    Of course, this will only work if you want to align ALL child elements to the bottom of the container rather than just, say, the last one – clayRay Feb 17 '21 at 23:19
8

The way I solved this was using flexbox. By using flexbox to layout the contents of your container div, you can have flexbox automatically distribute free space to an item above the one you want to have "stick to the bottom".

For example, say this is your container div with some other block elements inside it, and that the blue box (third one down) is a paragraph and the purple box (last one) is the one you want to have "stick to the bottom".

enter image description here

By setting this layout up with flexbox, you can set flex-grow: 1; on just the paragraph (blue box) and, if it is the only thing with flex-grow: 1;, it will be allocated ALL of the remaining space, pushing the element(s) after it to the bottom of the container like this:

enter image description here

(apologies for the terrible, quick-and-dirty graphics)

MoralCode
  • 1,954
  • 1
  • 20
  • 42
  • 3
    The same would also work with `margin-top: auto;` applied to the last element. – Domenik Reitzner Dec 11 '20 at 07:58
  • 2
    Don't forget to set flex-direction: column; for the container, as it defaults to row, which will try to squeeze in your elements next to each other horizontally. – clayRay Feb 18 '21 at 00:06
5

I came here looking, forgetting that I already knew the answer to this - and it's super-simple: display: flex and margin-top: auto.

All you need to do is give your container a display of flex and your items you want at the bottom a top margin of auto:

.container {
  display: flex;
}

.box {
  margin-top: auto;
}
<div class="container" style="border:1px solid red; height: 150px;">
    <div class="box" style="border:1px solid green; width:20px; height:20px;"></div>
    <div class="box" style="border:1px solid blue; width:20px; height:30px;"></div>
</div>

No need for floats or clears either.

indextwo
  • 5,535
  • 5
  • 48
  • 63
4

I don't like absolute positioning, either, because there is almost always some collateral damage, i.e. unintended side effects. Especially when you are working with a responsive design. There seems to be an alternative - the sandbag technique. By inserting a "helper" element, either in the markup of via CSS, we can push elements down to the bottom of the container. See http://community.sitepoint.com/t/css-floating-divs-to-the-bottom-inside-a-div/20932 for examples.

cdonner
  • 37,019
  • 22
  • 105
  • 153
1

You can cheat! Say your div is 20px high, place the div at the top of the next container and set

position: absolute;
top: -20px;

It may not be semantically clean but does scale with responsive designs

Derek
  • 2,092
  • 1
  • 24
  • 38
0

I would use grid for this.

#container {
  display: grid;
  grid-template-rows: min-content 1fr min-content;
  height: 100%;
}
#top {
  background-color: yellow;
}
#bottom {
  background-color: yellow;
}
html, body {
  height: 100%;
}
body {
  margin: 0;
}
<div id="container">
  <div id="top">
    <p>Top</p>
  </div>

  <div></div>

  <div id="bottom">
    <p>Bottom</p>
  </div>
</div>
Jacob
  • 135
  • 2
  • 12