SitePoint Sponsor

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 25 of 26
  1. #1
    SitePoint Addict
    Join Date
    Dec 2010
    Posts
    222
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Flexible DIV to cover the rest of the page and divide the height in half for children

    Here's a sample layout:

    Code:
    <!DOCTYPE html>
    <html>
    
    <head>
        <meta charset="UTF-8">
        <title>Dynamic DIV</title>
        <style>
            #header {
                background: green;
            }
            #header * {
                vertical-align: middle;
            }
            button {
                float: right;
            }
            #top {
                background: yellow;
            }
            #bottom {
                background: aqua;
            }
        </style>
    </head>
    
    <body>
        <div id="header">
            <label for="checker">Check</label>
            <input type="checkbox" id="checker">
            <label for="slider">Slider</label>
            <input type="range" id="slider"><span>Some text</span>
            <button type="button">Bar</button>
            <button type="button">Foo</button>
        </div>
        <div id="content">
            <div id="top">Top content</div>
            <div id="bottom">Bottom content</div>
        </div>
    </body>
    
    </html>

    Demo: http://jsfiddle.net/CZt36/1/

    How can I extend the content DIV to he rest of the page so that the top and bottom DIVs get 50% of the content DIV height?

  2. #2
    SitePoint Mentor bronze trophy
    ronpat's Avatar
    Join Date
    Jun 2012
    Location
    NJ, USA
    Posts
    2,519
    Mentioned
    61 Post(s)
    Tagged
    2 Thread(s)
    Normally we encourage folks to let the content dictate the height of the page except for a sticky footer perhaps. A couple of questions...

    Is the page expected to be responsive or fluid or will this be a fixed width page?

    Is the height of the page expected to extend longer than the height of the viewport or will the content be entirely visible in the window?

  3. #3
    SitePoint Addict
    Join Date
    Dec 2010
    Posts
    222
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ronpat View Post
    Is the page expected to be responsive or fluid or will this be a fixed width page?
    Fluid: 100%.

    Is the height of the page expected to extend longer than the height of the viewport or will the content be entirely visible in the window?
    The content will be entirely visible in the window with no scrollbars.
    No matter what screen resolution you use, the page should cover the viewport completely.

  4. #4
    SitePoint Mentor bronze trophy
    ronpat's Avatar
    Join Date
    Jun 2012
    Location
    NJ, USA
    Posts
    2,519
    Mentioned
    61 Post(s)
    Tagged
    2 Thread(s)
    Give this a try and see if it is something you can use.

    The height of the header box is fixed at 40px.

    The heights of #top and #bottom are 50% of the remaining screen height, as requested.

    Vertical scrollbars will be generated if content tries to extend any of those 3 containers. That means that only a limited amount of content is permitted and it should be equally distributed between #top and #bottom, OR the percentages of those two containers can be changed to whatever ratio is needed as long as they total 100%.

    This is not truly fluid in that the ratio of the heights of the boxes is not adaptable; however, you can use media queries when necessary to adjust the heights of the header and content boxes as needed.
    Code:
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>Dynamic DIV</title>
        <style>
    body {
        padding:0;
        margin:0;
    }
    *, *:before, *:after {
        -webkit-box-sizing:border-box;
        -moz-box-sizing:border-box;
        box-sizing:border-box;
    }
    #header {
        display:table;
        width:100%;
        height:40px;
        background:green;
    }
    .tcell {
        display:table-cell;
        vertical-align:middle;
    }
    #header * {
        vertical-align:middle;
    }
    button {
        float:right;
    }
    #content {
        position:absolute;
        top:40px;  /* same value as height of header */
        left:0;
        right:0;
        bottom:0;
    }
    #top,
    #bottom {
        position:absolute;
        height:50%;
        width:100%;
    }
    #top {
        background:yellow;
        top:0;
    }
    #bottom {
        background:aqua;
        bottom:0;
    }
        </style>
    </head>
    <body>
    
    <div id="header">
        <div class="tcell">
        <button type="button">Bar</button>
        <button type="button">Foo</button>
        <label for="checker">Check</label>
        <input type="checkbox" id="checker">
        <label for="slider">Slider</label>
        <input type="range" id="slider">
        <span>Some text</span>
        </div>
    </div>
    <div id="content">
        <div id="top">Top content</div>
        <div id="bottom">Bottom content</div>
    </div>
    
    </body>
    </html>

  5. #5
    SitePoint Addict
    Join Date
    Dec 2010
    Posts
    222
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ronpat View Post
    The height of the header box is fixed at 40px.
    Thanks for the answer!
    The header height changes from browser to browser unless we give it a larger fixed height as you did. But I want it to take up exactly the space it needs in any browser -- no more. Any approach without giving a fixed height to the header?

  6. #6
    The CSS Clinic is open silver trophybronze trophy
    Paul O'B's Avatar
    Join Date
    Jan 2003
    Location
    Hampshire UK
    Posts
    40,366
    Mentioned
    179 Post(s)
    Tagged
    6 Thread(s)
    You can do it with flexbox for modern browsers only.

    Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Untitled Document</title>
    <style>
    html, body {
    	margin:0;
    	padding:0
    }
    body {
    	display: flex;
    	height: 100vh;
    	flex-direction: column;
    }
    .content {
    	flex: 1;
    	overflow:auto
    }
    header { background:orange }
    main.content { background:blue }
    footer { background:red }
    </style>
    </head>
    
    <body>
    <header>
    		<button type="button">Bar</button>
    		<button type="button">Foo</button>
    		<label for="checker">Check</label>
    		<input type="checkbox" id="checker">
    		<label for="slider">Slider</label>
    		<input type="range" id="slider">
    		<span>Some text</span> </header>
    <main class="content">test</main>
    <footer  class="content">test</footer>
    </body>
    </html>

  7. #7
    SitePoint Addict
    Join Date
    Dec 2010
    Posts
    222
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ronpat View Post
    The height of the header box is fixed at 40px.
    Here's a screenshot showing the header height in IE11:

    win8.1_ie_11.0_Desktop.png

  8. #8
    SitePoint Mentor bronze trophy
    ronpat's Avatar
    Join Date
    Jun 2012
    Location
    NJ, USA
    Posts
    2,519
    Mentioned
    61 Post(s)
    Tagged
    2 Thread(s)
    The image is pending approval.

    I turned on my Win7 box and opened the file in IE11. The header looks really crummy. Not horizontally aligned well at all. I'll give it another go and see if I can improve that.

  9. #9
    The CSS Clinic is open silver trophybronze trophy
    Paul O'B's Avatar
    Join Date
    Jan 2003
    Location
    Hampshire UK
    Posts
    40,366
    Mentioned
    179 Post(s)
    Tagged
    6 Thread(s)
    Quote Originally Posted by ronpat View Post
    The image is pending approval.

    I turned on my Win7 box and opened the file in IE11. The header looks really crummy. Not horizontally aligned well at all. I'll give it another go and see if I can improve that.
    You need to take the default margin and padding out of the mix for IE11.
    Code:
    #header * { vertical-align:middle;margin:0;padding:0 }

  10. #10
    SitePoint Mentor bronze trophy
    ronpat's Avatar
    Join Date
    Jun 2012
    Location
    NJ, USA
    Posts
    2,519
    Mentioned
    61 Post(s)
    Tagged
    2 Thread(s)
    Quote Originally Posted by Paul O'B View Post
    You need to take the default margin and padding out of the mix for IE11.
    Code:
    #header * { vertical-align:middle;margin:0;padding:0 }
    I just learned about the default padding and was about to post just what you said, ninja Paul.

    You might want to set #header * {padding:0 auto;} to preserve the horizontal padding in the buttons,
    and add to the button {margin-left:10px;} to separate them a tad.

    Regarding the header height in the screen shot in post #7, it looks taller than 40px.

    Off Topic:

    @Paul O'B would you mind explaining how the flex-box example works? That is amazing stuff.

  11. #11
    SitePoint Wizard Stomme poes's Avatar
    Join Date
    Aug 2007
    Location
    Netherlands
    Posts
    10,278
    Mentioned
    50 Post(s)
    Tagged
    2 Thread(s)
    Quote Originally Posted by paul
    You need to take the default margin and padding out of the mix for IE11.
    Does this not kill default padding in form controls for other browsers though? The kind you can't add back in?

    Kudos for the main in the code :P

    Question on flexbox: if using flexbox and browsers don't know elements like <main> and <footer>, does flexbox just create their block-context or do you actually still have to display: block them for someone?

  12. #12
    The CSS Clinic is open silver trophybronze trophy
    Paul O'B's Avatar
    Join Date
    Jan 2003
    Location
    Hampshire UK
    Posts
    40,366
    Mentioned
    179 Post(s)
    Tagged
    6 Thread(s)
    Quote Originally Posted by Stomme poes View Post
    Does this not kill default padding in form controls for other browsers though? The kind you can't add back in?
    Browsers have changed a bit these days and the arguments for not removing padding and margins are not quite the same as they were. You may lose some visual clues such as the depress effect on submit buttons but you can replace this with other focus styles. I find it better to explicitly control the padding, margin and line-height on form elements these days for better results and I also use the border-box model for IE8 plus so that textareas and selects are the same widths as inputs.

    Whatever method you use there will always be a discrepancy so it's a matter of being careful and checking the results
    Kudos for the main in the code :P

    Question on flexbox: if using flexbox and browsers don't know elements like <main> and <footer>, does flexbox just create their block-context or do you actually still have to display: block them for someone?
    I usually set them to block in the default reset although modern browsers should know about them now (maybe not 'main' yet though) so yes if you had no 'reset' styles then the element should be set to block just in case when using flex.

    @Paul O'B would you mind explaining how the flex-box example works? That is amazing stuff.
    I'm just getting my head around it also but the basis of the demo was that the 100vh sets the element to 100% of the viewport height and the flex-direction: column; sets the child boxes to be stacked vertically rather than horizontally.

    The flex:1 on two of the children says that you want the space ratio that they occupy to be the same so the rest of the space in that element is evenly divided between those two items. If one was flex 2 then it would have twice the space as the other one and so on. The item without the flex1 just takes up its own space as required.

    It makes the sticky footer pretty easy as you can do the same sort of thing.

    Some demos here:

    http://www.sketchingwithcss.com/grow-shrink/
    http://www.sketchingwithcss.com/flex-container-2/
    http://www.sketchingwithcss.com/flexbox/
    http://www.sketchingwithcss.com/flex-container/

    The main problem is browsers support so it will be a couple of years before we can go mainstream with it without a fall-back.

  13. #13
    SitePoint Addict bronze trophy AllanP's Avatar
    Join Date
    Sep 2010
    Location
    Australia
    Posts
    298
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Here is a javascript method of doing the job (some CSS too ). I have attached the background image to this post. The script works in all browsers back to IE7. It makes use of the mousemove event to change the position of a slider block inside a div. The percentage position of the slider is used to set the height of the outer container. The top and bottom content are set at 50% of the container height. The fully collapsed state has been constrained to 40px to allow the content text to be readable.

    Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
    <title>Dynamic DIV</title>
    <script type="text/javascript">
     function show_coords(evt)
       { var elem, coords, heightVal;  
         elem=(evt.target)? evt.target : evt.srcElement; 
         coords={left:0, top:0};    
         if(evt.layerX)
          { coords.left=evt.layerX; coords.top=evt.layerY; }
         else if(evt.offsetX)
          { coords.left=evt.offsetX+1; coords.top=evt.offsetY+1; }
         evt.cancelBubble=true;
        // 
         var slidePosn=coords.left-5;   // allow for half width of slider block 
         holderObj.style.backgroundPosition=slidePosn+"px","0px";
         var indx=coords.left/parseInt(slideWidth)*100;  
         indx=(indx>=100)?100 :((indx<=0)? 0 :indx);
         outputObj.value="percent: " + parseInt(indx);
         heightVal=parseInt(contentHeight*indx/100); 
         heightVal=(heightVal<=40)? 30 : heightVal;
         contentObj.style.height=heightVal+"px";
       }
    // -----------
     var contentObj, outputObj, contentHeight, slideWidth; // global
     function init()
      { contentObj=document.getElementById("content") 
        contentHeight=400;                                 // height of outer container
        contentObj.style.height=contentHeight+"px"; 
        outputObj=document.getElementById("output"); 
        outputObj.value="Move slider";     
        holderObj=document.getElementById("holder");
        slideWidth=holderObj.style.width="200px";          // set width of slider
        holderObj.style.backgroundPosition=(parseInt(slideWidth)/2)-10+"px",0+"px"; // initial posn of slider block
      }
    </script>
    <style type="text/css">
    body   { font-family:arial, helvetica, sans-serif; font-weight:normal; font-size:16px; color:#000; font-weight:bold; text-align:left; margin:3px 0px; }
    #wrap  { width:500px; height:500px; margin-left:20px; }
    #header { position:relative; top:0px; left:0px; height:120px; background-color: green; overflow:auto; }
    #content { height:400px; margin-top:5px;  }
    #top    { height:50%; background-color: #FF0; padding:2px; }
    #bottom { height:50%; background-color: #0FF; padding:2px; }
    #holder { position:relative; top:0px; left:0px; border:1px solid white; width:200px; height:20px; margin-left:10px; cursor:pointer;  }
    /* note:   background image block1.jpg reqd. size 10x20px         */
    #holder { background-color:#444; background-image:url('block1.jpg'); background-repeat:no-repeat; background-position:0px,0px; }
    #output { margin:10px;  }
    .a14B   { font-size:14px; font-weight:bold; color:#FFF; margin:10px; }
    </style>
    </head>
    
    <body>
    
    <div id="wrap">
      <div id="header">
        <p class="a14B">Slide block to set height of content</p>
        <div id="holder" onmousemove="show_coords(event)">
        </div>
        <input id="output" type="text" value size="10" readonly>
      </div>
      <div id="content">
        <div id="top">
          Top content</div>
        <div id="bottom">
          Bottom content</div>
      </div>
    </div>
    <script type="text/javascript">
       window.onload=init;
     </script>
    
    </body>
    
    </html>
    Attached Images Attached Images

  14. #14
    SitePoint Addict
    Join Date
    Dec 2010
    Posts
    222
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by AllanP View Post
    Here is a javascript method of doing the job
    I'm working on a CSS solution.
    Thanks for the code anyway!

  15. #15
    The CSS Clinic is open silver trophybronze trophy
    Paul O'B's Avatar
    Join Date
    Jan 2003
    Location
    Hampshire UK
    Posts
    40,366
    Mentioned
    179 Post(s)
    Tagged
    6 Thread(s)
    Quote Originally Posted by AllanP View Post
    Here is a javascript method of doing the job (some CSS too ).
    Nice demo

  16. #16
    SitePoint Addict
    Join Date
    Dec 2010
    Posts
    222
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Paul O'B View Post
    You can do it with flexbox for modern browsers only.
    Many thanks for the answer! I've been busy doing some tests and playing around with ronpat's solution.
    I need to study flexbox before I use your code and will come back if I have more questions.

    Thanks again!

  17. #17
    SitePoint Addict
    Join Date
    Dec 2010
    Posts
    222
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Paul O'B View Post
    You need to take the default margin and padding out of the mix for IE11.
    Code:
    #header * { vertical-align:middle;margin:0;padding:0 }
    The only trouble maker is input type=range and removing its top and bottom padding seems to be enough to resolve the issue:
    Code:
    input[type="range"] {padding-top:0; padding-bottom:0;}

  18. #18
    SitePoint Addict
    Join Date
    Dec 2010
    Posts
    222
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ronpat View Post
    You might want to set #header * {padding:0 auto;} to preserve the horizontal padding in the buttons
    Internet Explorer is too stupid to understand it. We should either remove the padding completely, as Paul mentioned:
    Code:
    input[type="range"] {padding:0;}
    or top and bottom padding:
    Code:
    input[type="range"] {padding-top:0; padding-bottom:0;}
    Regarding the header height in the screen shot in post #7, it looks taller than 40px.
    60px, to be more accurate.

  19. #19
    SitePoint Mentor bronze trophy
    ronpat's Avatar
    Join Date
    Jun 2012
    Location
    NJ, USA
    Posts
    2,519
    Mentioned
    61 Post(s)
    Tagged
    2 Thread(s)
    Quote Originally Posted by Rain Lover View Post
    Internet Explorer is too stupid to understand it. We should either remove the padding completely, as Paul mentioned:
    Code:
    input[type="range"] {padding:0;}
    or top and bottom padding:
    Code:
    input[type="range"] {padding-top:0; padding-bottom:0;}
    I tested {padding:0 auto;} using IE11 before I posted that note and it seemed to work fine. However, being more specific like you did you can't go wrong. Thanks for the feedback

    Paul's flexbox solution is exciting! I'm reading up on it, too! Very neat stuff.

  20. #20
    SitePoint Addict
    Join Date
    Dec 2010
    Posts
    222
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Paul O'B View Post
    You can do it with flexbox for modern browsers only.

    Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Untitled Document</title>
    <style>
    html, body {
    	margin:0;
    	padding:0
    }
    body {
    	display: flex;
    	height: 100vh;
    	flex-direction: column;
    }
    .content {
    	flex: 1;
    	overflow:auto
    }
    header { background:orange }
    main.content { background:blue }
    footer { background:red }
    </style>
    </head>
    
    <body>
    <body>
    <header>
    		<button type="button">Bar</button>
    		<button type="button">Foo</button>
    		<label for="checker">Check</label>
    		<input type="checkbox" id="checker">
    		<label for="slider">Slider</label>
    		<input type="range" id="slider">
    		<span>Some text</span> </header>
    <main class="content">test</main>
    <footer  class="content">test</footer>
    </body>
    </body>
    </html>
    It seems like a bug in Chrome: 100vh doesn't stretch the page in zoom/F11. Here's the page I tried.

  21. #21
    The CSS Clinic is open silver trophybronze trophy
    Paul O'B's Avatar
    Join Date
    Jan 2003
    Location
    Hampshire UK
    Posts
    40,366
    Mentioned
    179 Post(s)
    Tagged
    6 Thread(s)
    Hi,

    Zoom doesn't effect chrome on your demo unless you have content that is suddenly stretched below the fold and then that content is no longer in the viewport and therefore should not have a background-colour. The vh unit means viewport height and not content height.

    There is a bug in chrome however if you grab the bottom of the window and drag it downwards then the background stays put and doesn't follow the viewport. However if you resize from the corner of the browser then the background does keep up with the viewport.

    Looks like Chrome still needs the old fashioned helper to make this work:

    Code:
    html{height:100%}
    Don't confuse the 'vh' unit with min-height:100%

  22. #22
    SitePoint Addict
    Join Date
    Dec 2010
    Posts
    222
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Paul O'B View Post
    Looks like Chrome still needs the old fashioned helper to make this work:

    Code:
    html{height:100%}
    Don't confuse the 'vh' unit with min-height:100%
    Thanks for the clarification!
    Instead of

    Code:
    html, body {margin:0; padding:0;}
    body {height:100vh;}
    can I use

    Code:
    html, body {margin:0; padding:0; height:100%;}
    It seems to resolve the Chrome zoom issue and works in different screen resolutions.

  23. #23
    The CSS Clinic is open silver trophybronze trophy
    Paul O'B's Avatar
    Join Date
    Jan 2003
    Location
    Hampshire UK
    Posts
    40,366
    Mentioned
    179 Post(s)
    Tagged
    6 Thread(s)
    Quote Originally Posted by Rain Lover View Post
    Thanks for the clarification!
    Instead of

    Code:
    html, body {margin:0; padding:0;}
    body {height:100vh;}
    can I use

    Code:
    html, body {margin:0; padding:0; height:100%;}
    Yes it will do the same job as the code I gave you. You are basically saying the same thing.

  24. #24
    SitePoint Addict
    Join Date
    Dec 2010
    Posts
    222
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Paul O'B View Post
    You can do it with flexbox for modern browsers only.
    Flexbox is great! You opened up a new horizon with lots of possibilities to me. Thank you!
    I wonder how I can put main and footer in your demo side by side while keeping the header at the top.

  25. #25
    The CSS Clinic is open silver trophybronze trophy
    Paul O'B's Avatar
    Join Date
    Jan 2003
    Location
    Hampshire UK
    Posts
    40,366
    Mentioned
    179 Post(s)
    Tagged
    6 Thread(s)
    Something like this I guess.

    Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Untitled Document</title>
    <style>
    html, body {
    	margin:0;
    	padding:0
    }
    html { height:100% }
    body {
    	display: flex;
    	height: 100vh;
    	flex-direction:column;
    }
    .content {
    	flex: 1 1;
    	justify-content: center;
    }
    header {
    	background:orange;
    	flex:none
    }
    main.content { background:blue; }
    footer {
    	background:red;
    	flex:1
    }
    .wrap {
    	display: flex;
    	flex-direction: row;
    	flex: 1 0px;
    }
    </style>
    </head>
    
    <body>
    <header>
    		<button type="button">Bar</button>
    		<button type="button">Foo</button>
    		<label for="checker">Check</label>
    		<input type="checkbox" id="checker">
    		<label for="slider">Slider</label>
    		<input type="range" id="slider">
    		<span>Some text</span> </header>
    <div class="wrap">
    		<main class="content">test</main>
    		<footer  class="content">test</footer>
    </div>
    </body>
    </html>
    I'm still trying to get my head around it also


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •