Skip to content Skip to sidebar Skip to footer

Pin Element (flex Item) To Bottom Of Container

I have a container to be the full window height/width. Inside this container I want a form that's vertically & horizontally centered. Below, I also want a piece of copy on the

Solution 1:

Updated Answer

With auto margins you can group or pack flex items together without extra markup, or shift elements around by applying a margin in the opposite direction (as seen in my original answer). In this case, simply set margin: auto on the form; this will inform the flex container to center the form within all available space remaining:

.flex-container {
  display: flex;
  flex-direction: column;
  text-align: center;
  height: 150px;
  width: 400px;
  background: #e7e7e7;
}
 
form {
  margin: auto;
}

p {
  margin: 0;
}
<divclass="flex-container"><form><inputtype="text" /><buttontype="submit">submit</button></form><pclass="bot">
    Lorem ipsum dolor sit amet
  </p></div>

See the other answers here for more insight:

In CSS Flexbox, why are there no "justify-items" and "justify-self" properties?

Can't scroll to top of flex item that is overflowing container


Original Answer

A clever way to "pin" a flex child is to give it an auto margin in the direction opposite of where you want it to go. In your case, you'd want to set

p.bot {
    margin-top: auto;
}

and the paragraph will shift to the bottom of the parent flex container. It works pretty well with simple layouts such as this...

html,
body {
  margin: 0;
  padding: 0;
}
.container {
  background-color: #eee;
  height: 100vh;
  width: 100vw;
  display: flex;
  text-align: center;
  justify-content: center;
  flex-direction: column;
  position: relative;
}
form {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.bot {
  margin-top: auto;
}
<divclass="container"><form><inputtype="text" /><buttontype="submit">submit</button></form><pclass="bot">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Omnis quae quisquam neque cupiditate adipisci magnam facilis, distinctio suscipit possimus hic voluptatibus in illo est id alias unde sapiente ab eius.</p></div>

Edit Note, I've also made the form a nested flexbox within the .container and set it's height to 100%, which is basically doing the same thing. Michael_B has a good explanation in the comments.

Solution 2:

You can create a pseudo element by using :before on the container, to make it as three sections, and use justify-content: space-between;

* {
    margin: 0;
}
.container {
    background-color: #eee;
    height: 100vh;
    width: 100vw;
    display: flex;
    justify-content: space-between;
    flex-direction: column;
    text-align: center;
}
.container:before {
    content: '';
}
<divclass="container"><form><inputtype="text" /><buttontype="submit">submit</button></form><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Omnis quae quisquam neque cupiditate adipisci magnam facilis, distinctio suscipit possimus hic voluptatibus in illo est id alias unde sapiente ab eius.</p></div>

jsfiddle

Solution 3:

Here's the problem you're having:

You have set the flex-direction to column. That means you've shifted the main axis to vertical, and the cross axis to horizontal.

The align-* properties work along the cross axis. So when you're telling .bot to align-self: flex-end, you're actually telling it to shift right, not down.

But it will not shift right in this case because the item is occupying the full width of the container and, therefore, has no space to move. However, if you limit it's width... http://jsfiddle.net/t7hap87o/

In wanting to pin <copy> to the bottom of the screen, flexbox has a bit of a limitation: There is no property similar to align-self for the main axis.

There are several other options to get the job done. You can nest flexboxes in the current container, or remove .bot from this container and place it in another.

Flexbox also allows for absolutely-positioned flex children. Try this:

.container {
    position: relative; /* establish nearest positioned ancestor for abs. positioning */
}

.bot {
    position: absolute;
    bottom: 0;
}

DEMO

Note: A margin-top: auto on .bot won't work in the current HTML structure. It would, in fact, pin the target element to the bottom. But it would also shove the centered element all the way to the top.

Solution 4:

The align-self: flex-end; doesn't have the desired affect, because the flex children are lined up as columns.

One easy way to line this up as desired, without adding any extra markup, is to:

  • move the footer element out of the .container

    <divclass="container"></div><pclass="bot"></p>
  • give the body (or another wrapper, if required) display: flex so that the .container and footer are flex children (siblings).

  • give .container a flex property of flex: 1 1 100%;. This will cause it to grow and shrink from its initial value of 100%. The footer is pushed down, but its height is accommodated for when the container shrinks.

  • give the footer a flex property of flex: 1 1 auto. This will now be pushed down the bottom, but will increase height with more contents.

Read more about the flex property over on the MDN.

Example

* {
  margin: 0;
  padding: 0;

}
body {
  display: flex;
  flex-direction: column;
  height: 100vh;
  width: 100vw;
}
.container {
  display: flex;
  flex: 11100%;
  flex-direction: column;
  justify-content: center;
  text-align: center;
  background: #EEE;
}
.bot {
  flex: 11 auto;
  text-align: center;
  background: #EEE;
  padding: 1em;
}
<divclass="container"><form><inputtype="text" /><buttontype="submit">submit</button></form></div><pclass="bot">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Omnis quae quisquam neque cupiditate adipisci magnam facilis, distinctio suscipit possimus hic voluptatibus in illo est id alias unde sapiente ab eius.</p>

Solution 5:

Change the flex-direction back to column, set one of the containers to width: 100% and use flex-wrap: wrap to achieve this.

Something like this (and it will work in Firefox and IE 10+ with vendor prefixes):

.container {
  background-color: #333;
  width: 100%;
  height: 100vh;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: center;
}

.footer {
  width: 100px;
  height: 20px;
  margin-top: -20px; /* set the margin top to negative what the 
                        height is so the form is perfectly centered */background-color: #900;
  color: #fff;
  text-align: center;
}

.form-wrapper {
  width: 100%; /* needs to be 100% to force the items to wrap */height: 50px;
  background-color: #009;
  
  /* center the form inside the wrapper */display: flex;
  align-items: center;
  justify-content: center;
}
<divclass="container"><divclass="form-wrapper"><form><inputtype="text"><buttontype="submit">submit</button></form></div><divclass="footer">footer content</div></div>

Post a Comment for "Pin Element (flex Item) To Bottom Of Container"