10

I have a very simple structure:

<div class="parent">
    <h1>Element taking space</h1>
    <div class="stretch">
        Not much content, but needs to be stretched to the end.
    </div>
</div>

The parent div has a set height, and I want div.stretch to stretch all the way to that height, regardless of how little content it has. Using height: 100% does the trick, until you add some other element which pushes the content down.

I guess that specifying height: 100% means that the element should have the exact same absolute/computed height as the parent element, and not the remainder of the height after all the other elements have been computed.

Setting overflow: hidden obviously hides the overflowing content, but that's not an option for me.

Is there any way I can achieve that in pure CSS?

Demo of my problem

Sunyatasattva
  • 5,619
  • 3
  • 27
  • 37
  • Use `position: absolute;` on your `div.stretch`, you'll need to add `position: relative;` to your `div.parent` http://jsbin.com/amesox/1/edit – gaynorvader Apr 10 '13 at 16:38
  • Will you know the height of `

    `? I'm not positive, but you may be able to use a negative margin (minus the height of h1) from stretch...

    – Adam Plocher Apr 10 '13 at 16:39
  • @AdamPlocher In this specific case, indeed I know the height of my `h1`. But this may not be the case in the future (I actually patched this specific case by using `overflow: hidden`), so I would like to find a solution that may apply to this general problem. – Sunyatasattva Apr 10 '13 at 16:45
  • Same here cannot see solution for that, I would use overflow:hidden property. In your example, what about giving the dark color to the container, and the clear color to the h1 tag, such as here http://jsbin.com/acotam/2/edit ?? – Jako Apr 10 '13 at 17:02
  • @Jako I gave background colors to the elements just for example sake, in order to show how elements behave, and where they are. In my specific case, I actually had to use border, and the specific problem would be much more like [**this example**](http://jsbin.com/ebojok/3/edit) I posted to thgaskell's answer. – Sunyatasattva Apr 10 '13 at 17:05

5 Answers5

12

In the time since this question was asked and answered, a better way to achieve this has come into existence: flex-box.

Just set the parent's display to "flex" and flex-direction to "column", and set the "stretchy" child's height to "inherit". The child will inherit a height of however many pixels are left over to fill up its parent.

In the following example, lines marked /* important */ are part of the actual solution; the rest of the CSS is just to make it visually easier to understand.

.parent {
  display: flex; /* important */
  flex-direction: column; /* important */
  height: 150px;
  border: 6px solid green;
}

h1 {
  background: blue;
  margin: 0px;
  height: 90px
}

.stretch {
  background: red;
  height: inherit; /* important */
}
<div class="parent">
    <h1>Element taking space</h1>
    <div class="stretch">
        Not much content, but needs to be stretched to the end.
    </div>
</div>
Alex von Brandenfels
  • 1,608
  • 15
  • 25
3

You could float the h1 element. It would work no matter what height it is, and the content of the stretch element will be pushed below it. But I'm not entirely sure if this is what you are looking for.

EDIT: I'm not certain what kind of browser support you're looking for, but you could also set the display to table on .parent and then have .stretch inherit the height. Then you can nest the column divs inside of .stretch and float them.

Updated: http://jsbin.com/oluyin/2/edit

HTML

<div class="parent">
    <h1>Element taking space</h1>
    <div class="stretch">
        <div class="col">Not much content, but needs to be stretched to the end.</div>
        <div class="col">Not much content, but needs to be stretched to the end.</div>
    </div>
</div>

CSS

.parent {
    display: table;
}

.stretch {
    height: inherit;
}

.col {
    float: left;
    width: 50%;
}
thgaskell
  • 12,772
  • 5
  • 32
  • 38
  • As long as the background color isn't important, this seems like the best way. +1 for you good sir – Adam Plocher Apr 10 '13 at 16:46
  • 1
    This is an interesting solution. To entirely work, it is necessary to add `width: 100%` to the `h1` though, as it is only a coincidence that the floated heading pushes the content down. Unfortunately, this doesn't solve the problem because of the way elements end up being layed out. Check [**this example**](http://jsbin.com/ebojok/4/edit) in which, other than the background, the border gets messed up; and [**this other example**](http://jsbin.com/ebojok/3/edit) in which the children need to be floated as well. – Sunyatasattva Apr 10 '13 at 16:54
  • Updated the answer. It looks like webkit browsers collapse margins, so the top margin of the h1 isn't contained in `.parent`. I think you can just swap the margin with padding to get the spacing around the element. If all else fails, there's javascript :) – thgaskell Apr 10 '13 at 18:09
  • This is definitely a comprehensive solution to the problem. I like it. – Sunyatasattva Apr 11 '13 at 10:25
1

If you know the height of your H1 you can do this to fill out the child:

.parent {

  background-color: #eee;
  border: 1px solid black;
  width: 300px;
  height: 600px;
  position:relative;

}

h1 { Height: 100px; }

.stretch
{
  background-color:#dddddd;
  position: absolute;
  left: 0;
  width: 100%;
  top: 100px;
  bottom: 0;
}

Example: http://jsbin.com/apocuh/1/edit

If you don't know the height of H1, I'm afraid you will probably need to use JavaScript or thgaskell's method.

Take a look at this post for more information, and an example with JS: CSS: height- fill out rest of div?

Community
  • 1
  • 1
Adam Plocher
  • 13,994
  • 6
  • 46
  • 79
1

Maybe using display:table properties fits your needs ?

Edit: This answer actually looks like thgaskell's one, but instead of using floats I use table-row and table-cell display, and it seems to achieve what you are looking for.

Here is the jsfiddle : http://jsbin.com/ebojok/17/edit

.parent {

  background-color: #eee;
  border: 1px solid black;
  width: 600px;
  height: 600px;
  display:table;

}

h1{
  display:table-row;
  width:100%;
}


.stretch{

  vertical-align:top;
  display:table-cell;
  height:100%;
  background-color: #ddd;

}
Jako
  • 944
  • 14
  • 33
  • 1
    Gee, I was unsure whether to accept this or thgaskell's answer, but I guessed I'd accept the latter since it came earlier. Get my upvote though! :) – Sunyatasattva Apr 11 '13 at 10:26
-1

HTML

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
  <div class="parent">
    <h1>Element taking space</h1>
    <div class="stretch">Not much content, but needs to be stretched to the end.</div>
  </div>
</body>
</html>

CSS

.parent {

  background-color: #eee;
  border: 1px solid black;
  width: 300px;
  height: 600px;
  position:relative;

}

.stretch {

  background-color: #ddd;
  height: 100%;
  position: absolute;  
  top: 0;
}

http://jsbin.com/amesox/1/edit

This will cover your h1 element as the .stretched goes over it. You could get around this by using z-index: 1; on your h1 element, but I'd advise against it if you want text in your .stretched element.

You need position:relative; on your parent div to give position: absolute something to 'hook on' to. absolute positioned elements, ignore other elements and are placed on top of them unless their z-index is higher or they are its children.

gaynorvader
  • 2,619
  • 3
  • 18
  • 32