5

I want to have a dynamic height div inside another wrapper, which always fill parent container, and auto shrink its size with displaying a vertical scrollbar for user to scroll should overflow happens.

Illustration below is what I'm expecting:

CSS

Currently the content pane just overflow the wrapper and pushing footer pane out of sight too.

Fiddle here http://jsfiddle.net/WWcAz/1/

#wrapper{
    padding: 10px;   
    vertical-align: middle;
    background-color: cyan;
    min-height: 100px;
    height: 300px;
    max-height: 300px;    
}

#dynamic{
    background-color: green;
    overflow: auto;
    overflow-x: hidden;
    min-height: 40px;
}

Is this possible with pure CSS?

(** Update:) I do not want any scrollbar with my wrapper, and wrapper has to be fix size, hope this is clear - thanks :)

Kagawa
  • 1,319
  • 2
  • 21
  • 33

4 Answers4

6

As far as I know this can only be done with Flexbox.

FIDDLE

(Relevant) CSS

#wrapper{
    padding: 10px;   
    vertical-align: middle;
    background-color: cyan;
    min-height: 100px;
    max-height: 300px; 
    -ms-box-orient: vertical;
   display: -ms-flex;
   height: 100%;
   display: -webkit-box;   /* OLD: Safari,  iOS, Android browser, older WebKit browsers.  */
   display: -moz-flex; 
   display: -ms-flexbox;   /* MID: IE 10 */
   display: -webkit-flex;  /* NEW, Chrome 21+ */ 
   display: flex;          /* NEW: Opera 12.1, Firefox 22+ */    

   -ms-flex-direction: column; 
   -webkit-flex-direction: column;
   flex-direction: column;
   -moz-box-sizing: border-box;
   box-sizing: border-box;
}
#content
{
    -ms-flex: 1 1 auto;
    -webkit-flex: 1 1 auto;
    flex: 1 1 auto;
    overflow: auto;
    height:0;
    min-height: 0;
}

A few points to mention:

0) (EDIT:)In order to get the scroll only on the (green) content I had to slightly change the markup to put the yellow area in the header.

1) I only apply flex-grow:1 (ie flex: 1 1 auto) to the scrollable content; the other items can have a fixed or dynamic height.

2) There's a hack(?) that I saw here, that placing height:0 on the container elements triggers a vertical scroll bar. (Here I used both height and min-height because this hack only worked in firefox with min-height)

3) For this to work in Firefox < 22 - you need to enable the flexbox runtime flag like this

4) Support for flexbox is surprisingly good in modern browsers (see here) but you need to add some browser specific css to get this working (see the above fiddle)

Community
  • 1
  • 1
Danield
  • 121,619
  • 37
  • 226
  • 255
1

I believe this is the structure you are after. You will of course have to modify it according to your specific size requirements.

FIDDLE

HTML

<div id="wrapper">
    <div id="header">Header</div>
    <div id="content"></div>
    <div id="footer">Footer</div>    
</div>

CSS

#wrapper{
position: relative;
background: #f5f5f5;
height: 400px;
margin: 0;
padding:  10px;
}

#header, #footer{
    position: absolute;
    background: #000;
    color: #fff;
    height: 20px;
    width: 100%;
    margin-left: -10px;
}

#header{
    top: 0;
}

#footer{
    bottom: 0;
}

#content{
    position: absolute;
    top: 20px;
    bottom: 20px;
    overflow: auto;
    width: 100%;
    margin-left: -10px;
}
reggaemahn
  • 6,272
  • 6
  • 34
  • 59
  • No, I don't want any scrollbar for my wrapper, and wrapper has to be a fixed size. I just want the inner dynamic DIV to be really smart and adjust itself. – Kagawa Aug 15 '13 at 10:44
  • You cannot do that because you have a font size set to 1000% (What's up with that?). You'll have to change that. – reggaemahn Aug 15 '13 at 10:47
  • that's just to show that i have some contents in the DIV, it should not bother with this question anyway (You may remove the font style and replace with a few rows of data) – Kagawa Aug 15 '13 at 10:50
  • I hope you understand this correctly. You have a box which you have set to a fixed height, So, obviously you cannot have stuff inside that box that are bigger than that size. What you need to do is apply % heights but again you'll need to be careful about the contents of the fixed height div because everything inside (height + padding + margin) should not exceed the size of the container div otherwise it will overflow. – reggaemahn Aug 15 '13 at 10:54
  • Thanks, i appreciate and understand your point totally. But it seems you're the one not getting it. I want the dynamic DIV to be able to fill the remaining height of wrapper DIV and able to shrink smaller if more space is needed in wrapper DIV to show other info. Vertical scrollbar should be displayed if content DIV is shrinked, so user can still see ALL information even its height is longer than the parent box. Hope this makes sense. – Kagawa Aug 15 '13 at 11:53
  • @Kagawa Yes, it does. It would have made sense earlier if you had mentioned that you are willing for the content div to be overloaded in the question. Check my updated answer. – reggaemahn Aug 15 '13 at 13:37
0

I can't see your image (blocked by firewall) however to do as you described you can do the following:

#dynamic{
   position: absolute;
   width: 100%;
   top: 0;
   bottom: 0;
   overflow: auto;
}

#wrapper {
   position: relative;
}

By setting position: absolute and setting both the top and bottom properties to 0 you are forcing it to take up the height of the offsetParent. You are also telling it that if it's size is less than it's content then to make it's overflow scrollable.

Obviously this brings it's own problems as the element has to be absolutely positioned and taken out of the regular document flow. You will need to do some restructuring most likely.

George Reith
  • 13,132
  • 18
  • 79
  • 148
0

Try this style. This will give a result like your second image. I am not sure about your first result, doing it completely in CSS.

body,html
{
    height: 97%;
}

#wrapper
{
    padding: 1%;   
    vertical-align: middle;
    background-color: cyan;
    height: 100%;   
}

#expand{
    background-color: yellow;

}

#dynamic{
    background-color: green;
    position : relative;
    height : 50%;
    overflow-y: scroll;
    overflow-x:hidden;
}

#header,#footer
{
    background-color: purple;
    height: 7%;
}

#content
{
    height: 86%;
}
Leo T Abraham
  • 2,407
  • 4
  • 28
  • 54