3

I have a container div that is a fixed height. It has some content and another child element. I would like the child element to scroll when it has filled the remaining height.

I came up with a solution that seems to work, but I'm not sure it is correct.

<style type="text/css">
  #container {height: 100px; width: 100px; border: solid; }
  #titlebar { background: gray;}
  #app-body {height: 100px; overflow: auto; background: lightblue;}    
</style>

Working fiddle. Edit: updated fiddle to remove style tags.

Is there a better way? I don't like restating the container height in the child div.

Rick Jolly
  • 2,949
  • 2
  • 23
  • 31
  • 1
    Your fiddle is broken. ` – millimoose Jun 03 '13 at 22:15
  • In fact, your CSS renders even worse: http://jsfiddle.net/millimoose/6VKUt/ – millimoose Jun 03 '13 at 22:16
  • 2
    Anyway, I don't think you have a choice. `overflow` simply won't do anything on an element without a constrained size, and I'm not sure there's a way to say, in CSS, "100% of the space remaining". (Short of using flexbox or tables.) The rule of thumb is CSS is terrible at using up vertical space. – millimoose Jun 03 '13 at 22:20
  • 1
    An unfortunately unfeasible flexbox solution: http://jsfiddle.net/millimoose/6VKUt/1/. (My suggestion here would be to give up and use tables until CSS ceases to be awful for layouts that aren't column-based grids.) – millimoose Jun 03 '13 at 22:38
  • Thanks. I'd mark that flexbox solution as an accepted answer if I could. – Rick Jolly Jun 03 '13 at 22:49

3 Answers3

1

Here is an experimental CSS possibility note - i made the height and width of the container wider to see it more clearly.

 #container {
      height: 200px;
      width: 200px;
      border: solid;
    overflow: auto;
  }
  #titlebar {
      background: gray;
  }
  #body {
      height:calc(100% - 4em); /* definitely non standard - the 4 em is an approximate size of the titlebar*/
      overflow: auto;
      background: lightblue;
  }

/*Old answer - disregard */

/*#container {
    height: 100px;
    width: 100px;
    border: solid;
    overflow:auto;   /* overflow belongs here *//*
}
#titlebar {
    background: gray;
}
#app-body {

    background: lightblue;
}*/
Taha Paksu
  • 15,371
  • 2
  • 44
  • 78
fnostro
  • 4,531
  • 1
  • 15
  • 23
  • 2
    -1: This doesn't actually do what the OP wants to do which is to only have the content scroll, and have the title bar remain in place. – millimoose Jun 03 '13 at 22:24
  • @millimoose: the OP doesn't state that. The above will indeed scroll the child content. I'm not a mind reader and I don't pretend to know what he's trying to accomplish – fnostro Jun 03 '13 at 22:33
  • 1
    @frostro It's sufficient to be a text reader! "[The 'container div'] has some content and another child element. I would like the child element to scroll when it has filled the remaining height." Relating that to the structure of the sample in the fiddle, 'container div' would refer to `#container`, `some content` would refer to `#titlebar`, and `another child element` seems to be `#body`. The last two could possibly be the other way around, but it's very clear the element that should be scrolling is *something else* than `#container`. – millimoose Jun 03 '13 at 22:36
  • millimoose is correct. I could have phrased the question better. +1 for trying. – Rick Jolly Jun 03 '13 at 22:40
  • Regarding your edit. Unfortunately I won't know the height of the title bar in advance so that won't work for me. – Rick Jolly Jun 03 '13 at 23:04
1

Display:table could be usefull:
Demo http://jsfiddle.net/GCyrillus/Vedkw/1
Firefox dislike it, child from display:table-row, behaves like table-cell, logic

html, body {height:100%;width:100%;margin:0;}
#container {display:table;height:100%;width:100%;}
#titlebar, #body {display:table-row;height:100%;}
/* overwrite height of titlebar */
#titlebar{height:auto;}

EDIT: digg a little please, THIS is a basic layout and you can use it.b
Inner content of #body can scroll .

G-Cyrillus
  • 101,410
  • 14
  • 105
  • 129
  • you may add a footer with table-row and height:auto; it will stick to botttom – G-Cyrillus Jun 03 '13 at 22:41
  • And where exactly is the scroll on child ? Read this from OP `I would like the child element to scroll when it has filled the remaining height.` – Sourabh Jun 03 '13 at 22:44
  • -1: This doesn't really constrain the width of the container. (And when I tried to do so, the table would just expand: http://jsfiddle.net/millimoose/Vedkw/2/) – millimoose Jun 03 '13 at 22:46
  • Well , a base is to be used. from that, add inner div and see it scroll – G-Cyrillus Jun 03 '13 at 22:47
  • @GCyrillus How about *you* use the base, and provide an answer to the question as stated, instead of just one step in the direction of it maybe. (Also, you need to update the link in your answer to the current version of your fiddle.) – millimoose Jun 03 '13 at 22:51
  • @GCyrillus As far as I can tell the container still isn't constrained vertically. – millimoose Jun 03 '13 at 22:52
  • @ millimoosei started with : Display:table could be usefull: and for your try, you need to use inherit height from parent to have it working. So from Html down to where you need it . else , it turns to be 100% of nothing. this is basic CSS rule. – G-Cyrillus Jun 03 '13 at 22:54
  • Last fiddle will scroll the body div in Chrome, but not Firefox. Thanks for your effort though. – Rick Jolly Jun 03 '13 at 23:02
  • @GCyrillus Needed resizing the window, so it's not necessarily obvious it works. You should still consider cleaning the answer up to be complete. – millimoose Jun 03 '13 at 23:04
  • @millimoose, thx for testing ;) .@approots , oh my god, too bad – G-Cyrillus Jun 03 '13 at 23:20
  • @GCyrillus Here's a cleaned up version of your fiddle: http://jsfiddle.net/millimoose/WySFZ/3/ (Still won't work in FF.) – millimoose Jun 03 '13 at 23:43
  • @milimoose, i discovered it too , memory tricks sometimes, i believed it used to – G-Cyrillus Jun 03 '13 at 23:46
  • @millimoose @GCyrillus Wrapping the content of `#body` in a `position: relative` then a `position: absolute` div seems to make it works on FF and IE too: http://jsfiddle.net/jce1d9zv/2/ I have not tested on IE>9 yet but on IE9 the scrollable content is the table height. – PSWai Aug 21 '14 at 09:32
0

Are you looking for this: Fiddle

I think this is only possible if you set the height of #body. Else it just flows, overflow: scroll on it or overflow: hidden on #container has no effect. And to set its height, you have to know/set the height of #titlebar.

I think jQuery can solve this height problem easily.

CSS

#container {
    height: 250px;
    border: solid;
    /*overflow: hidden*/ /* <-- not really needed if height of sub-elements*/
                         /* is <= child of container */
}
#titlebar {
    height: 60px;
    background: gray;
}
#body {
    height: 190px;
    overflow-y: scroll;
}

EDIT

I think making a block element the height remaining is not possible by just CSS as elements take as much height they need and not as much height available, unless specified.

If you can use script, see this fiddle

jQuery

var $body = $('div#body');
var h = $body.parent('div').height()
        - $body.siblings('div#titlebar').height();
$body.height(h);

CSS

#container {
    height: 250px;
    border: solid;
    overflow: hidden
}
#titlebar {
    background: gray;
}
#body {
    overflow-y: scroll;
}
Sourabh
  • 8,243
  • 10
  • 52
  • 98
  • The OP says that he doesn't want to restate the container height on the children. I understood this as implying he doesn't want to use explicit heights anywhere else than on the container. I.e. letting the titlebar have a height "as needed", and have the content have "the rest". Using exact pixel dimensions and absolute positioning can "solve" any CSS problem but is rarely a feasible approach/ – millimoose Jun 03 '13 at 22:44
  • I don't know the height of the titlebar content ahead of time, so unfortunately this won't work. I'll use javascript or flexbox. – Rick Jolly Jun 03 '13 at 22:54