Align an element to bottom with flexbox

HtmlCssFlexbox

Html Problem Overview


I have a div with some children:

<div class="content">
  <h1>heading 1</h1>
  <h2>heading 2</h2>
  <p>Some more or less text</p>
  <a href="/" class="button">Click me</a>
</div>

and I want the following layout:

 -------------------
|heading 1          |
|heading 2          | 
|paragraph text     |
|can have many      |
|rows               |
|                   |
|                   |
|                   | 
|link-button        |
 -------------------

Regardless how much text is in the p I want to stick the .button always at the bottom without taking it out of the flow. I've heard this can be achievable with Flexbox but I can't get it to work.

Html Solutions


Solution 1 - Html

You can use auto margins

> Prior to alignment via justify-content and align-self, > any positive free space is distributed to auto margins in that > dimension.

So you can use one of these (or both):

p { margin-bottom: auto; } /* Push following elements to the bottom */
a { margin-top: auto; } /* Push it and following elements to the bottom */

.content {
  height: 200px;
  border: 1px solid;
  display: flex;
  flex-direction: column;
}
h1, h2 {
  margin: 0;
}
a {
  margin-top: auto;
}

<div class="content">
  <h1>heading 1</h1>
  <h2>heading 2</h2>
  <p>Some text more or less</p>
  <a href="/" class="button">Click me</a>
</div>

Alternatively, you can make the element before the a grow to fill the available space:

p { flex-grow: 1; } /* Grow to fill available space */

.content {
  height: 200px;
  border: 1px solid;
  display: flex;
  flex-direction: column;
}
h1, h2 {
  margin: 0;
}
p {
  flex-grow: 1;
}

<div class="content">
  <h1>heading 1</h1>
  <h2>heading 2</h2>
  <p>Some text more or less</p>
  <a href="/" class="button">Click me</a>
</div>

Solution 2 - Html

You can use display: flex to position an element to the bottom, but I do not think you want to use flex in this case, as it will affect all of your elements.

To position an element to the bottom using flex try this:

.container {
  display: flex;
}

.button {
  align-self: flex-end;
}

Your best bet is to set position: absolute to the button and set it to bottom: 0, or you can place the button outside the container and use negative transform: translateY(-100%) to bring it in the container like this:

.content {
    height: 400px;
    background: #000;
    color: #fff;
}
.button {
    transform: translateY(-100%);
    display: inline-block;
}

Check this JSFiddle

Solution 3 - Html

1. Style parent element: style="display:flex; flex-direction:column; flex:1;"

2. Style the element you want to stay at bottom: style="margin-top: auto;"

3. Done! Wow. That was easy.

Example:

enter image description here

section {
  /* ONLY FOR DEMO, NOT NECESSARY */
  display: flex;
  flex-wrap: wrap;
}

div {
  /* PARENT ELEMENT */
  display: flex;
  flex-direction: column;
  flex: 1;
}

button {
  /* TARGET ELEMENT */
  margin-top: auto;
}

/* DECORATIVE STYLES FOR DEMO */

button {
  font-size: 20px;
  background-color: crimson;
  color: white;
  border-style: none;
  border-radius: 3px;
}

section {
  margin: 0;
  padding: 0;
  border: 1px solid black;
  background-color: crimson;
}

div {
  font-size: 20px;
  background-color: khaki;
  border: 2px dashed black;
  margin: 10px;
  padding: 10px;
  min-width: 400px;
  min-height: 300px;
}

<section>
  <div>
    <span>Lorem ipsum dolor s at mi imperdiet fringilla vitae id lorem. Donec ut semper sapien, et ullamcorper metu</span>
    <button>I</button>
  </div>
  <div>
    <span>Lorem ipsum dolor sit amet</span
    ><button>
      stay
    </button>
  </div>
  <div>
    <span
      >Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi at augue ac turpis fringilla egestas. quis mi diam. Quisque faucibus, massa non finibus iaculis, arcu nulla auctor enim, quis accumsan dolor odio quis turpis. Duis convallis pulvinar justo sit amet feugiat.
      Duis sed lectus at mi imperdiet fringilla vitae id lorem. Donec ut semper sapien, et ullamcorper metu</span
    >
    <button>
      at
    </button>
  </div>
  <div>
    <span>Lorem ipsum dolor sit amet</span
    ><button>
      bottom
    </button>
  </div>
  <div>
    <span>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi at augue ac turpis fringilla egestas. Donec quis mctus at mi imperdiet fringilla vitae id lorem. Donec ut semper sapien, et ullamcorper metu</span>
    <button>
      always
    </button>
  </div>
  <div>
    <span>Lorem ipsum dolor sit amet sit amet, consectetur adipiscing elit. Morbi at augue ac turpis fringilla egestas. Donec quis mctus at mi imperdiet fringilla vitae id lorem. Donec ut semper sapien, et ullamcorper</span
    ><button>
      all ways
    </button>
  </div>
</section>

Solution 4 - Html

The solution with align-self: flex-end; didn't work for me but this one did in case you want to use flex:

Result

 -------------------
|heading 1          |
|heading 2          | 
|paragraph text     |
|                   |
|                   |
|                   | 
|link button        |
 -------------------

Code

Note: When "running the code snippet" you have to scroll down to see the link at the bottom.

.content {
  display: flex;
  justify-content: space-between;
  flex-direction: column;
  height: 300px;
}

.content .upper {
  justify-content: normal;
}

/* Just to show container boundaries */
.content .upper, .content .bottom, .content .upper > * {
  border: 1px solid #ccc;
}

<div class="content">
  <div class="upper">
	  <h1>heading 1</h1>
	  <h2>heading 2</h2>
	  <p>paragraph text</p>
  </div>

  <div class="bottom">
	  <a href="/" class="button">link button</a>
  </div>
</div>

Solution 5 - Html

When setting your display to flex, you could simply use the flex property to mark which content can grow and which content cannot.

Flex property

div.content {
 height: 300px;
 display: flex;
 flex-direction: column;
}

div.up {
  flex: 1;
}

div.down {
  flex: none;
}

<div class="content">
  <div class="up">
    <h1>heading 1</h1>
    <h2>heading 2</h2>
    <p>Some more or less text</p>
  </div>

  <div class="down">
    <a href="/" class="button">Click me</a>
  </div>
</div>

Solution 6 - Html

If it's fine to modify your HTML, you can wrap all your top elements in a separate div and then use justify-content: space-between.

Something like this:

<div class="content">
  <div>
    <h1>heading 1</h1>
    <h2>heading 2</h2>
    <p>Some more or less text</p>
  </div>
  <a href="/" class="button">Click me</a>
</div>
.content {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

Solution 7 - Html

Not sure about flexbox but you can do using the position property.

set parent div position: relative and child element which might be an <p> or <h1> etc.. set position: absolute and bottom: 0.

Example:

index.html

<div class="parent">
  <p>Child</p>
</div>

style.css

.parent {
  background: gray;
  width: 10%;
  height: 100px;    
  position: relative;
}
p {
  position: absolute;
  bottom: 0;
}

Code pen here.

Solution 8 - Html

<div class="content">
    <h1>heading 1</h1>
    <h2>heading 2</h2>
    <p>Some more or less text</p>
    <a href="/" class="button">Click me</a>
</div>

Notes for CSS:

  1. Change the height of .content as you need
  2. Button will take the whole empty area at the bottom because of the flex:1 property, making the whole area clickable. I will advise wrapping the button in a div or span

CSS

.content {
    display: flex;
    flex-direction: column;
    height: 100vh;
}

.button {
    display: flex;
    flex: 1;
    align-items: flex-end;
}

https://codepen.io/alokjain_lucky/pen/MWooJGw

Solution 9 - Html

I just found a solution for this.

for those who are not satisfied with the given answers can try this approach with flexbox

CSS

    .myFlexContainer {
        display: flex;
        width: 100%;
    }

    .myFlexChild {
        width: 100%;
        display: flex;

        /* 
         * set this property if this is set to column by other css class 
         *  that is used by your target element 
         */
        flex-direction: row;
        
        /* 
         * necessary for our goal 
         */
        flex-wrap: wrap;
        height: 500px;
    }
    
    /* the element you want to put at the bottom */
    .myTargetElement {
        /*
         * will not work unless flex-wrap is set to wrap and 
         * flex-direction is set to row
         */
        align-self: flex-end;
    }

HTML

    <div class="myFlexContainer">
        <div class="myFlexChild">
            <p>this is just sample</p>
            <a class="myTargetElement" href="#">set this to bottom</a>
        </div>
    </div>

Solution 10 - Html

Try This

.content {
      display: flex;
      flex-direction: column;
      height: 250px;
      width: 200px;
      border: solid;
      word-wrap: break-word;
    }

   .content h1 , .content h2 {
     margin-bottom: 0px;
    }

   .content p {
     flex: 1;
    }

   <div class="content">
  <h1>heading 1</h1>
  <h2>heading 2</h2>
  <p>Some more or less text</p>
  <a href="/" class="button">Click me</a>
</div>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsupersizeView Question on Stackoverflow
Solution 1 - HtmlOriolView Answer on Stackoverflow
Solution 2 - HtmlRoumelis GeorgeView Answer on Stackoverflow
Solution 3 - HtmlFeritView Answer on Stackoverflow
Solution 4 - HtmlTimo ErnstView Answer on Stackoverflow
Solution 5 - HtmlTomas VancoillieView Answer on Stackoverflow
Solution 6 - HtmlStanley SathlerView Answer on Stackoverflow
Solution 7 - HtmlSanjay ShrView Answer on Stackoverflow
Solution 8 - HtmlAlok JainView Answer on Stackoverflow
Solution 9 - Htmlaj goView Answer on Stackoverflow
Solution 10 - Htmlmohxn ayazView Answer on Stackoverflow