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>
Linas
  • 4,380
  • 17
  • 69
  • 117
  • Just by the way; you have an extra closing div. Looks like you're trying to close `
    ` twice
    – TylerH Jan 02 '16 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. – Roope Jan 02 '16 at 21:37
  • @Roope Yes footer should be fixed and content fill in the rest of the space – Linas Jan 02 '16 at 21:38
  • And should the content be scrollable in case of overflow, or how? – Roope Jan 02 '16 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 – Linas Jan 02 '16 at 21:41
  • Set height auto no need to defin value – devpro Jan 02 '16 at 21:46
  • Should the footer always be visible when the content is bigger, which means that the scroll should appear on the content div? – Asons Jan 02 '16 at 22:00
  • Don't use `display:table`, use `display:flex` instead. This should be relatively straight forward then, with the footer being stretch:0 and the content with stretch:1 – Aleks G Jan 02 '16 at 22:07

5 Answers5

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>
Asons
  • 84,923
  • 12
  • 110
  • 165
  • 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 Jan 02 '16 at 22:15
  • @vals Do leave it, it is a good and actually better way with `flex` than `display: table` ... :) – Asons Jan 02 '16 at 22:17
  • Unfortunately this solution does not seem to be working on firefox for me. – Linas Jan 02 '16 at 23:22
  • @Linas Checked that and it is a bug in FF, https://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: fixed`or `position: absolute`, well maybe also `table-layout: fixed` would work. – Asons Jan 03 '16 at 10:15
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>
Paulie_D
  • 107,962
  • 13
  • 142
  • 161
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>
Roope
  • 4,469
  • 2
  • 27
  • 51
  • 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. – Linas Jan 02 '16 at 21:56
  • 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? – Roope Jan 02 '16 at 22:01
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;
}
devpro
  • 16,184
  • 3
  • 27
  • 38
  • 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 Jan 02 '16 at 21:52
  • @linas yes when u set height auto it will manage automatically as per content size – devpro Jan 02 '16 at 21:54
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/

digglemister
  • 1,477
  • 3
  • 16
  • 31
  • Go for `calc` only if everything else fails. There are likely other simple solutions that will work in all browsers. – Roope Jan 02 '16 at 21:56