By kristof


2009-02-25 13:15:09 8 Comments

Say I have the following CSS and HTML code:

#header {
  height: 150px;
}
<div id="header">
  <h1>Header title</h1>
  Header content (one or multiple lines)
</div>

The header section is fixed height, but the header content may change.

I would like the content of the header to be vertically aligned to the bottom of the header section, so the last line of text "sticks" to the bottom of the header section.

So if there is only one line of text, it would be like:

-----------------------------
| Header title
|
|
|
| header content (resulting in one line)
-----------------------------

And if there were three lines:

-----------------------------
| Header title
|
| header content (which is so
| much stuff that it perfectly
| spans over three lines)
-----------------------------

How can this be done in CSS?

25 comments

@mickburkejnr 2011-08-11 15:33:28

I have devised a way which is a lot simpler than what's been mentioned.

Set the height of the header div. Then inside that, style your H1 tag as follows:

float: left;
padding: 90px 10px 11px

I'm working on a site for a client, and the design requires the text to be at the bottom of a certain div. I've achieved the result using these two lines, and it works fine. Also, if the text does expand, the padding will still remain the same.

@Mozfet 2019-05-16 14:21:46

Will cause content to float over other content when resizing screens using responsive layouts.

@Patrick McElhaney 2009-02-25 13:18:51

Use CSS positioning:

/* Creates a new stacking context on the header */
#header {
  position: relative;
}

/* Positions header-content at the bottom of header's context */
#header-content {
  position: absolute;
  bottom: 0;
}

As cletus noted, you need identify the header-content to make this work.

<span id="header-content">some header content</span>

<div style="height:100%; position:relative;">
    <div style="height:10%; position:absolute; bottom:0px;">bottom</div>
</div>

@dsdsdsdsd 2013-11-05 16:28:32

fyi ... this caused my header-content to collapse its width, so I had to add a width = '100%' on the header-content

@Patrick McElhaney 2014-04-22 20:37:10

@dsdsdsdsd You could also fix that by adding display:block to #header-content.

@BadHorsie 2017-07-19 13:19:03

@dsdsdsdsd The reason is because <span> elements have display: inline; by default, which does not take up the full width of the container. The most appropriate fix would be to change the span to a <div>, which is a block element by default.

@Patrick McElhaney 2017-07-19 16:38:14

Or one of <h1> - <h6> which is also block by default and identifies the text as a header, which is useful to search engines, assistive technologies, and people reading the code.

@Mozfet 2019-05-16 14:30:17

Does not work when the content on the bottom has variable height, causes it to extend out of the container bounds.

@Mozfet 2019-05-16 14:19:16

All these answers and none worked for me... I'm no flexbox expert, but this was reasonably easy to figure out, it is simple and easy to understand and use. To separate something from the rest of the content, insert an empty div and let it grow to fill the space.

https://jsfiddle.net/8sfeLmgd/1/

.myContainer {
  display: flex;
  height: 250px;
  flex-flow: column;
}

.filler {
  flex: 1 1;
}

<div class="myContainer">
  <div>Top</div>
  <div class="filler"></div>
  <div>Bottom</div>
</div>

This reacts as expected when the bottom content is not fixed sized also when the container is not fixed sized.

@MK Vimalan 2018-05-23 06:08:28

You can simply achieved flex

header {
  border: 1px solid blue;
  height: 150px;
  display: flex;                   /* defines flexbox */
  flex-direction: column;          /* top to bottom */
  justify-content: space-between;  /* first item at start, last at end */
}
h1 {
  margin: 0;
}
<header>
  <h1>Header title</h1>
  Some text aligns to the bottom
</header>

@Pablo Contreras 2018-02-01 13:17:23

a very simple, one-line solution, is to add line-heigth to the div, having in mind that all the div's text will go bottom.

CSS:

#layer{width:198px;
       height:48px;
       line-height:72px;
       border:1px #000 solid}
#layer a{text-decoration:none;}

HTML:

<div id="layer">
    <a href="#">text at div's bottom.</a>
</div>

keep in mind that this is a practical and fast solution when you just want text inside div to go down, if you need to combine images and stuff, you will have to code a bit more complex and responsive CSS

@Temani Afif 2017-12-28 22:01:09

Here is another solution using flexbox but without using flex-end for bottom alignment. The idea is to set margin-bottom on h1 to auto to push the remaining content to the bottom:

#header {
  height: 350px;
  display:flex;
  flex-direction:column;
  border:1px solid;
}

#header h1 {
 margin-bottom:auto;
}
<div id="header">
  <h1>Header title</h1>
  Header content (one or multiple lines) Header content (one or multiple lines)Header content (one or multiple lines) Header content (one or multiple lines)
</div>

We can also do the same with margin-top:auto on the text but in this case we need to wrap it inside a div or span:

#header {
  height: 350px;
  display:flex;
  flex-direction:column;
  border:1px solid;
}

#header span {
 margin-top:auto;
}
<div id="header">
  <h1>Header title</h1>
  <span>Header content (one or multiple lines)</span>
</div>

@Grace Nikole 2019-10-26 18:36:53

Perfecto! gracias

@user841657 2017-10-22 23:56:59

#header {
    height: 150px;
    display:flex;
    flex-direction:column;
}

.top{
    flex: 1;
}   

<div id="header">
    <h1 class="top">Header title</h1>
    Header content (one or multiple lines)
</div>

#header {
    height: 250px;
    display:flex;
    flex-direction:column;
    background-color:yellow;
}

.top{
    flex: 1;
}
<div id="header">
    <h1 class="top">Header title</h1>
    Header content (one or multiple lines)
</div>

@Mozfet 2019-05-16 14:23:35

This causes resizing of the top div. Which works for basic text layouts, but does not work when things have backgrounds and colors and sizes to respect.

@cletus 2009-02-25 13:20:01

Relative+absolute positioning is your best bet:

#header {
  position: relative;
  min-height: 150px;
}

#header-content {
  position: absolute;
  bottom: 0;
  left: 0;
}

#header, #header * {
  background: rgba(40, 40, 100, 0.25);
}
<div id="header">
  <h1>Title</h1>
  <div id="header-content">Some content</div>
</div>

But you may run into issues with that. When I tried it I had problems with dropdown menus appearing below the content. It's just not pretty.

Honestly, for vertical centering issues and, well, any vertical alignment issues with the items aren't fixed height, it's easier just to use tables.

Example: Can you do this HTML layout without using tables?

@kristof 2009-02-25 13:49:04

I actually found that solution before asking here, but somehow forgot to add the position: relative; to the header div and the content kept landing at the bottom of the page. Thanks

@Alejandro García Iglesias 2012-07-25 19:16:46

You can manage your dropdown position with the z-index property to bring it to front. Remember that the z-index property works with elements positioned relatively or absolutely. Also, is not correct semantically speaking to use a table to achieve layout results.

@Josh Burgess 2014-02-11 21:18:30

In the case of text content as described in the original problem, #header-content should really be a p element, or at the very least a span

@Adrien Be 2014-06-03 12:49:41

if #header has a fixed height, here is a quick hack: #header-content { position: relative; bottom: -4px; } (change the -4px to whatever value works for you), this is kinda dirty but has the advantage of letting #header keep its positioning (ie. static) if required. Otherwise, go for @Cletus solution.

@bafromca 2014-10-29 02:29:08

This doesn't allow the content to scroll if the content is shorter than container.

@Dima Gimburg 2015-06-17 12:20:29

also if you want to align to the center (like text-align: center) you can use : left: 0; right: 0; in addition to what Cletus said.

@Jeremy Moritz 2015-07-15 21:21:14

Don't use tables for non-tabular data! Instead, use the CSS display properties display: table-cell, or table-row, or table. You never again need to use tables for pure layout.

@stack1 2015-08-18 18:24:15

Header position is relative to what ?

@Soleil 2018-01-27 14:19:50

This fails in react components; the right and modern way is the flexbox way.

@Ligemer 2018-03-21 03:07:37

I disagree with @Jeremy-DeerAngel-org and agree with the accepted answer, sometimes tables are the right choice. Don't sacrifice layout stability with the "don't use tables" ideology. Tables are usually not the right choice with our modern JS frameworks, but tables sometimes are the best approach for the layout.

@Mozfet 2019-05-16 14:30:55

Does not work when the content on the bottom has variable height, causes it to extend out of the container bounds.

@user3053247 2017-04-24 04:31:32

display: flex;
align-items: flex-end;

@AnthonyB 2017-05-02 15:20:25

Note that flexbox is not well supported in old browsers.

@Tisch 2017-09-07 15:23:41

@AnthonyB - define old? We have to change this record as developers. Technology moves forward, and the old simply don't survive. IE9 and 10 have issues with flex from what I can see, but they were released in 2011 and 2012 respectively... it's 2017. We have to let go of these outdated and broken browsers. If not for visual satisfaction, but for security and general software updates.

@AnthonyB 2017-09-07 15:29:06

@Tisch you're absolutely right we have to, as developers, use decent and recent technology. But I'd simply warn about this compatibility issue, in order to not to be surprised.

@agapitocandemor 2018-03-07 15:14:54

if the content under the <h1> is inside a <p> or <div> I would use justify-content: space-between.

@Stickers 2016-11-24 02:53:46

The modern way to do it would be using flexbox. See the example below. You don't even need to wrap Some text... into any HTML tag, since text directly contained in a flex container is wrapped in an anonymous flex item.

header {
  border: 1px solid blue;
  height: 150px;
  display: flex;                   /* defines flexbox */
  flex-direction: column;          /* top to bottom */
  justify-content: space-between;  /* first item at start, last at end */
}
h1 {
  margin: 0;
}
<header>
  <h1>Header title</h1>
  Some text aligns to the bottom
</header>

If there is only some text and you want to align vertically to the bottom of the container.

section {
  border: 1px solid blue;
  height: 150px;
  display: flex;                   /* defines flexbox */
  align-items: flex-end;           /* bottom of the box */
}
<section>Some text aligns to the bottom</section>

@Swen 2017-02-27 10:14:32

I needed my bottom-aligned element to still be present in the document flow, which isn't possible when using position:absolute;. This solution worked perfectly for my case!

@Soleil 2018-01-27 14:18:40

Inside react components, this is the right solution. The accepted solution fails.

@B.K. 2018-02-27 22:19:09

This is the only solution that actually worked for me. Maybe it has to do with React, as @Soleil has mentioned... I am not a CSS expert, so I'm not entirely sure.

@XMaster 2016-11-09 09:42:44

I found this solution bassed on a default bootstrap start template

/* HTML */

<div class="content_wrapper">
  <div class="content_floating">
    <h2>HIS This is the header<br>
      In Two Rows</h2>
    <p>This is a description at the bottom too</p> 
  </div>
</div>

/* css */

.content_wrapper{
      display: table;
      width: 100%;
      height: 100%; /* For at least Firefox */
      min-height: 100%;
    }

.content_floating{
  display: table-cell;
  vertical-align: bottom;
  padding-bottom:80px;

}

@absynthe minded web smith 2016-06-07 20:33:12

Here's the flexy way to do it. Of course, it's not supported by IE8, as the user needed 7 years ago. Depending on what you need to support, some of these can be done away with.

Still, it would be nice if there was a way to do this without an outer container, just have the text align itself within it's own self.

#header {
    -webkit-box-align: end;
    -webkit-align-items: flex-end;
    -ms-flex-align: end;
    align-items: flex-end;
    display: -webkit-box;
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex;
    height: 150px;
}

@Greg Prisament 2014-07-18 17:11:31

After struggling with this same issue for some time, I finally figured out a solution that meets all of my requirements:

  • Does not require that I know the container's height.
  • Unlike relative+absolute solutions, the content doesn't float in its own layer (i.e., it embeds normally in the container div).
  • Works across browsers (IE8+).
  • Simple to implement.

The solution just takes one <div>, which I call the "aligner":

CSS

.bottom_aligner {
    display: inline-block;
    height: 100%;
    vertical-align: bottom;
    width: 0px;
}

html

<div class="bottom_aligner"></div>
... Your content here ...

This trick works by creating a tall, skinny div, which pushes the text baseline to the bottom of the container.

Here is a complete example that achieves what the OP was asking for. I've made the "bottom_aligner" thick and red for demonstration purposes only.

CSS:

.outer-container {
  border: 2px solid black;
  height: 175px;
  width: 300px;
}

.top-section {
  background: lightgreen;
  height: 50%;
}

.bottom-section {
  background: lightblue;
  height: 50%;
  margin: 8px;
}

.bottom-aligner {
  display: inline-block;
  height: 100%;
  vertical-align: bottom;
  width: 3px;
  background: red;
}

.bottom-content {
  display: inline-block;
}

.top-content {
  padding: 8px;
}

HTML:

<body>
  <div class="outer-container">
    <div class="top-section">
      This text
      <br> is on top.
    </div>
    <div class="bottom-section">
      <div class="bottom-aligner"></div>
      <div class="bottom-content">
        I like it here
        <br> at the bottom.
      </div>
    </div>
  </div>
</body>

Align bottom content

@Gaston Sanchez 2015-05-16 00:23:43

Almost perfect :) but it doesn't allow automatic line breaks.

@ecraig12345 2015-06-22 21:08:55

Doesn't work if outer-container can scroll (overflow-y: auto). :(

@Graham Perrin 2015-07-07 09:10:56

I guess that marin:8px should be margin:8px

@Sheepy 2016-04-27 03:33:49

This also works if put in a ::before rule, which removes the need of an extra element. We used flex at the end, but this is useful when you can't.

@BairDev 2017-06-27 12:02:10

This is a really nice solution. It works only if the height of the box/container and its parents is set (to px or % or whatever).

@Admin File3 2016-02-22 19:17:50

Seems to be working:

HTML: I'm at the bottom

css:

h1.alignBtm {
  line-height: 3em;
}
h1.alignBtm span {
  line-height: 1.2em;
  vertical-align: bottom;
}

@Tam Mai 2009-04-25 09:43:38

I use these properties and it works!

#header {
  display: table-cell;
  vertical-align: bottom;
}

@random_user_name 2012-06-05 22:47:55

Isn't supported in IE8 and earlier. It IS supported in IE9.

@Zach Lysobey 2013-02-28 19:08:21

@cale_b According to caniuse.com it DOES work in IE8.

@Daniel Szabo 2013-12-18 07:12:13

@ZachL Happenstance - I'm supporting a legacy app in IE8 for a corporate client and this does in fact work.

@Daniel Szabo 2013-12-18 07:14:19

@fguillen: tested in Chrome (v31) just now as well. Works there, too.

@Nathan J.B. 2014-04-26 19:19:20

NOTE: table-cell will not allow you to use min-height (at least in Chrome 34). Sadly, that was a requirement for me, otherwise this'd be the exact solution I was looking for. (Still gets my upvote!)

@Noah 2014-12-30 20:27:20

table-cell breaks a lot of things. Like the Bootstrap grid system. col-md-12 won't give you a 100% wide div anymore.

@Atomosk 2016-07-15 05:13:49

Doesn't work if content of #header has display: block.

@Atomosk 2016-08-29 02:38:06

@Gavin Hmm, it certanly didn't work for me and switching display of content changed it. Sadly I can't remember exact example. But yours stops working if I set position: absolute to #header. Would be nice if there were all the additional conditions required. Like position shouldn't be absolute.

@Gavin 2016-08-30 09:10:29

@Atomosk yes, setting a display: table-cell element to position: absolute will have undesired consequences.

@JohnFF 2017-03-04 14:29:26

I like this - great for collapsing a row of divs with a header as the first element on a mobile.

@Timothy Gonzalez 2018-02-02 20:48:52

This could be an issue if you want to use a flex box for your content.

@romiem 2014-02-20 17:55:09

If you have multiple, dynamic height items, use the CSS display values of table and table-cell:

HTML

<html>
<body>

  <div class="valign bottom">
    <div>

      <div>my bottom aligned div 1</div>
      <div>my bottom aligned div 2</div>
      <div>my bottom aligned div 3</div>

    </div>
  </div>

</body>
</html>

CSS

html,
body {
  width: 100%;
  height: 100%;
}
.valign {
  display: table;
  width: 100%;
  height: 100%;
}
.valign > div {
  display: table-cell;
  width: 100%;
  height: 100%;
}
.valign.bottom > div {
  vertical-align: bottom;
}

I've created a JSBin demo here: http://jsbin.com/INOnAkuF/2/edit

The demo also has an example how to vertically center align using the same technique.

@Nicki L. Hansen 2013-10-15 07:35:23

The site I just did for a client requested that the footer text was a high box, with the text at the bottom I achieved this with simple padding, should work for all browsers.

<div id="footer">
  some text here
</div>
#footer {
  padding: 0 30px;
  padding-top: 60px;
  padding-bottom: 8px;
}

@Andrew 2013-10-15 07:57:23

Your first declaration padding: 0 30px is a bit redundant, you may as well have put padding: 30px then the other 2 declarations.

@Nicki L. Hansen 2013-10-15 08:07:57

Absolutely true, however I'm following the practices of my workplace.

@Zach Lysobey 2013-12-18 15:10:15

Really?, that seems like plain bad practice. Just use the shorthand, or be explicit everywhere. padding: 60px 30px 8px;, padding: 60px 30px 8px 30px;, four explicit padding- rules, or even @TheWaxMann's suggestion are all superior - and I'm willing and able to argue that one ;-)

@dougwig 2012-12-04 22:16:43

Inline or inline-block elements can be aligned to the bottom of block level elements if the line-height of the parent/block element is greater than that of the inline element.*

markup:

<h1 class="alignBtm"><span>I'm at the bottom</span></h1>

css:

h1.alignBtm {
  line-height: 3em;
}
h1.alignBtm span {
  line-height: 1.2em;
  vertical-align: bottom;
}

*make sure you're in standards mode

@Aditya Ponkshe 2015-02-06 12:49:56

You don't need absolute+relative for this. It is very much possible using relative position for both container and data. This is how you do it.

Assume height of your data is going to be x. Your container is relative and footer is also relative. All you have to do is add to your data

bottom: -webkit-calc(-100% + x);

Your data will always be at the bottom of your container. Works even if you have container with dynamic height.

HTML will be like this

<div class="container">
  <div class="data"></div>
</div>

CSS will be like this

.container{
  height:400px;
  width:600px;
  border:1px solid red;
  margin-top:50px;
  margin-left:50px;
  display:block;
}
.data{
  width:100%;
  height:40px;
  position:relative;
   float:left;
  border:1px solid blue;
  bottom: -webkit-calc(-100% + 40px);
   bottom:calc(-100% + 40px);
}

Live example here

Hope this helps.

@mhatch 2016-12-19 16:47:10

Can you explain what bottom: -webkit-calc(-100% + x); is doing?

@Aditya Ponkshe 2017-03-20 11:53:33

@mhatch it keeps footer at the bottom of the container.

@Lee Irvine 2014-08-25 20:46:03

If you're not worried about legacy browsers use a flexbox.

The parent element needs its display type set to flex

div.parent {
  display: flex;
  height: 100%;
}

Then you set the child element's align-self to flex-end.

span.child {
  display: inline-block;
  align-self: flex-end;
}

Here's the resource I used to learn: http://css-tricks.com/snippets/css/a-guide-to-flexbox/

@Lee Irvine 2015-01-22 18:25:29

@bafromca, two reasons that doesn't work. 1: Use 'align-self' instead of align-items (my fault, I've edited my original post). 2: 100% height won't work unless the parent has height.

@Mozfet 2019-05-16 14:29:06

Did not work for me, I want it at the bottom of the container, not the end of the items in the container.

@waza123 2015-01-10 22:56:34

2015 solution

<div style='width:200px; height:60px; border:1px solid red;'>

    <table width=100% height=100% cellspacing=0 cellpadding=0 border=0>
        <tr><td valign=bottom>{$This_text_at_bottom}</td></tr>
    </table>

</div>

http://codepen.io/anon/pen/qERMdx

your welcome

@undeniablyrob 2015-11-19 16:16:35

Table layout for this can be problematic; CSS is recommended instead. The valign property is also not supported in HTML5. (see w3schools.com/tags/att_td_valign.asp)

@codeboy 2014-07-12 07:28:33

if you could set the height of the wrapping div of the content (#header-content as shown in other's reply), instead of the entire #header, maybe you can also try this approach:

HTML

<div id="header">
    <h1>some title</h1>
    <div id="header-content">
        <span>
            first line of header text<br>
            second line of header text<br>
            third, last line of header text
        </span>
    </div>
</div>

CSS

#header-content{
    height:100px;
}

#header-content::before{
  display:inline-block;
  content:'';
  height:100%;
  vertical-align:bottom;
}

#header-content span{
    display:inline-block;
}

show on codepen

@Fakeer 2011-08-11 21:12:44

A perfect cross-browser example is probably this one here:

http://www.csszengarden.com/?cssfile=/213/213.css&page=0

The idea is both to display the div at the bottom and also making it stick there. Often the simple approach will make the sticky div scroll up with the main content.

Following is a fully working minimal example. Note that there's no div embedding trickery required. The many BRs are just to force a scrollbar to appear:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        #floater {
            background: yellow;
            height: 200px;
            width: 100%;
            position: fixed;
            bottom: 0px;
            z-index: 5;
            border-top: 2px solid gold;
        }

    </style>
</head>


<body>
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>


    <div id="floater"></div>
</body>
</html>

If you are wondering your code might not be working on IE, remember to add the DOCTYPE tag at the top. It's crucial for this to work on IE. Also, this should be the first tag and nothing should appear above it.

@Amos M. Carpenter 2011-11-14 06:17:27

Since you're declaring your document as XHTML strict, you should also self-close your <br /> tags...

@Razor 2012-12-14 13:16:17

@KarlKildén if you were referring to the comment from aaamos, it most definitely isn't a silly comment - serving the above document with its correct content-type header would result in the browser throwing an xml parsing error.

@m93a 2013-09-28 11:14:31

This is a bad practise! Use CSS instead!

@felix 2013-01-21 03:46:31

try with:

div.myclass { margin-top: 100%; }

try changing the % to fix it. Example: 120% or 90% ...etc.

@Mike Graf 2013-02-08 16:42:15

Works perfectly fine with 1 set of content, but will need to be adjusted if the content changes. If it's dynamic content, then dont use this!

@esp 2013-01-04 14:31:56

Seems to be working:

#content {
    /* or just insert a number with "px" if you're fighting CSS without lesscss.org :) */
    vertical-align: [email protected]_height + @content_height;

    /* only need it if your content is <div>,
     * if it is inline (e.g., <a>) will work without it */
    display: inline-block;
}

Using less makes solving CSS puzzles much more like coding than like... I just love CSS. It's a real pleasure when you can change the whole layout (without breaking it :) just by changing one parameter.

Related Questions

Sponsored Content

103 Answered Questions

[SOLVED] How to horizontally center a <div>

44 Answered Questions

[SOLVED] How to disable text selection highlighting

32 Answered Questions

[SOLVED] How to make a div 100% height of the browser window

  • 2009-10-15 21:18:43
  • mike
  • 1874155 View
  • 2027 Score
  • 32 Answer
  • Tags:   html css height

38 Answered Questions

[SOLVED] How can I make a div not larger than its contents?

  • 2009-01-16 16:03:07
  • George Snider
  • 1351340 View
  • 1972 Score
  • 38 Answer
  • Tags:   html css width

35 Answered Questions

[SOLVED] How to vertically align an image inside a div

38 Answered Questions

[SOLVED] How do I vertically center text with CSS?

21 Answered Questions

[SOLVED] Vertically align text next to an image?

30 Answered Questions

[SOLVED] How do I vertically align text in a div?

16 Answered Questions

[SOLVED] How do I disable the resizable property of a textarea?

  • 2011-03-08 16:15:40
  • user549757
  • 1285415 View
  • 2548 Score
  • 16 Answer
  • Tags:   html css

31 Answered Questions

[SOLVED] Make a div fill the height of the remaining screen space

  • 2008-09-18 05:06:17
  • Vincent McNabb
  • 918980 View
  • 1756 Score
  • 31 Answer
  • Tags:   html css html-table

Sponsored Content