6

What I have is a simple structure of container followed by two child elements, contentand footer.

footer has a fixed height and content should fill remaining empty space. That is easy enough to achieve with display:table; but for some reason I can't figure out how to make content element overflow to work if its contents exceed website window height?

Here is a JSFiddle, if you set content_child height to say 10pxyou can see content element filling up the space nicely but when content_child is a lot bigger content element shouldn't expand the way it does now, what am i missing here?

I would prefer to not use JavaScript to solve this if possible.

body, html{
  height: 100%;
  padding: 0px;
  margin: 0px;
}

.container{
  display:table;
  background; black;
  width: 100%;
  background: black;
  height: 100%;
}
.top{
  background: blue;
  display:table-row;
  height: 100%;
}

.bottom{
  background: red;
  height: 60px;
}

.content{
  height: 100%;
  overflow: hidden;
  padding: 5px;
}

.content_child{
  height: 1000px;
  background: grey;
}
<div class="container">
    <div class="top">
      <div class="content">
          <div class="content_child"></div>
          </div>
      </div>
  </div>
  <div class="bottom">
  </div>
</div>

8
  • Just by the way; you have an extra closing div. Looks like you're trying to close <div class="content_child"> twice Commented Jan 2, 2016 at 21:35
  • Do you want a fixed footer or what are you trying to achieve? Anyway, there are most likely better ways to achieve what you are trying to do than using tables. So let's not start from the solution but rather the problem. Commented Jan 2, 2016 at 21:37
  • @Roope Yes footer should be fixed and content fill in the rest of the space Commented Jan 2, 2016 at 21:38
  • And should the content be scrollable in case of overflow, or how? Commented Jan 2, 2016 at 21:39
  • @roope content should always fill in the remaining space on the website, if its contents are bigger than the website it should have overflow-y: scroll Commented Jan 2, 2016 at 21:41

5 Answers 5

4

Flexbox can do that.

body {
 margin:0;
 }

.container {
  height: 100vh;
  display: flex;
  flex-direction: column;
}
.content {
  flex: 1;
  background: #bada55;
  overflow-y: auto;
}
.expander {
  height: 1000px;
  /* for demo purposes */
}
footer {
  background: red;
  height: 60px;
}
<div class="container">
  <div class="content">
    <div class="expander"></div>
  </div>
  <footer></footer>
</div>

Sign up to request clarification or add additional context in comments.

2 Comments

You need to fix body margin to avoid the body scroll...
It's just to demo the technique...no need to overload the demo..but why not.
4

The only thing you need to do is to change this CSS rule

.content{
  height: 100%;
  overflow: auto;   /* change from hidden to auto */
  padding: 5px;
}

which will make it look/work like this

body, html{
  height: 100%;
  padding: 0px;
  margin: 0px;
}

.container{
  display:table;
  background; black;
  width: 100%;
  background: black;
  height: 100%;
}
.top{
  background: blue;
  display:table-row;
  height: 100%;
}

.bottom{
  background: red;
  height: 60px;
}

.content{
  height: 100%;
  overflow: auto;
  padding: 5px;
}

.content_child{
  height: 1000px;
  background: grey;
}
<div class="container">
  <div class="top">
    <div class="content">
      <div class="content_child"></div>
    </div>
  </div>
  <div class="bottom">  
  </div>
</div>

4 Comments

I didn't see your answer... Otherwise I wouldn't have post mine. Anyway I will leave it as an alternative way to solve this
@vals Do leave it, it is a good and actually better way with flex than display: table ... :)
Unfortunately this solution does not seem to be working on firefox for me.
@Linas Checked that and it is a bug in FF, bugzilla.mozilla.org/show_bug.cgi?id=565111, so my suggestion is to use flex and then create a fallback for those who don't know flex using display: table. If you can set a fixed height on your bottom div you can of course use position: fixedor position: absolute, well maybe also table-layout: fixed would work.
2

No need for tables, really. Depending on what you are trying to achieve, this may work for you:

body {
  padding: 0;
  margin: 0;
}
.content {
  position: fixed;
  top: 0;
  bottom: 50px;
  width: 100%;
  background: blue;
  color: #fff;
  overflow-y: auto;
}
.footer {
  position: fixed;
  bottom: 0;
  height: 50px;
  width: 100%;
  background: red;
}
<div class="content">
  <p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
  <p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
  <p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
  <p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
  <p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
  <p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
  <p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
  <p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
</div>
<div class="footer"></div>

And if there's no fancier purpose, you could always just change the body background, the same end result here with less code. The only difference is that the scroll bar shows above the footer as well in this one.

body {
  padding: 0;
  margin: 0;
  background: blue;
  color: #fff;
}
.footer {
  position: fixed;
  bottom: 0;
  height: 50px;
  width: 100%;
  background: red;
}
<p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
<p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
<p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
<p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
<p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
<p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
<p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
<p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
<div class="footer"></div>

2 Comments

Well this seems to work, but it's a dirty hack to do it with position: fixed; I actually need to implement this into a part of my website so it would't really work. I tried to simplify my example as much as i could, sorry for confusing it.
How would it really not work, i.e. what makes it a dirty hack? Anyway, what is the downside for you on the second simple way?
2

I hope this will help if you set height as auto

body, html{
  padding: 0px;
  margin: 0px;
}

.container{
  display:table;
  background; black;
  width: 100%;
  background: black;
  height: auto;
}
.top{
  background: blue;
  display:table-row;
  height: auto;
}

.bottom{
  background: red;
  height: 60px;
}

.content{
  height: auto;
  overflow: hidden;
  padding: 5px;
}

.content_child{
  height: auto;
  background: grey;
}

2 Comments

Sorry mate you missed the point of content_child, it's just an example, i don't actually know what height its going to have...
@linas yes when u set height auto it will manage automatically as per content size
1

Maybe use calc() for height of .top instead of using display: table

.top{
    background: blue;
    height: calc(100% - 70px);
    padding: 5px;
}

.content{
    height: 100%;
    overflow-y: scroll;
}

Check out this working fiddle: https://jsfiddle.net/xyxj02ge/4/

1 Comment

Go for calc only if everything else fails. There are likely other simple solutions that will work in all browsers.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.