Pergunta

I have a very simple CSS 100% example, that logically as I understand it, should work, but doesn't. Can someone please explain why?

HTML:

<div id="header">header</div>
<div id="nav">Nav</div>
<div id="title">title</div>
<div id="content">
    Content
</div>

CSS:

html {
    height:100%;
    padding: 0;
    margin: 0;
}
body {
    height: 100%;
    padding: 0;
    margin: 0;
}
#header {
    background-color:red;
    padding: 0;
    margin: 0;
}
#nav {
    background-color:gray;
    padding: 0;
    margin: 0;
}
#title {
    background-color:azure;
    padding: 0;
    margin: 0;
}
#content {
    background-color:antiquewhite;
    height:100%;
    padding: 0;
    margin: 0;
}

To my understanding, there should be no vertical scroll bar. Yet one appears.

Here is a fiddle to demonstrate: http://jsfiddle.net/codeowl/9wABW/

Thank you for your time,

Regards,

Scott

UPDATE:

Here is what I ended up doing:

I developed a stack and fill approach as follows. Unfortunately fiddle has an issue with me trying to access the window in java script, so I can only paste the code:

CSS:

#header {
    background-color:red;
}
#nav {
    background-color:gray;
}
#title {
    background-color:azure;
}
#content {
    background:green;
}

HTML:

<div id="header" class="stack-y">header</div>
<div id="nav" class="stack-y">Nav</div>
<div id="title" class="stack-y">title</div>
<div id="content" class="fill-y">
    <div data-role="splitter"
        data-panes="[
        { scrollable: false, collapsible: true, size: '300px' },
        { scrollable: false, collapsible: true }
        ]" 
        class="fill-y">
        <div>
            Left Pane
        </div>
        <div>
            Right Pane
        </div>
    </div>
    <div class="stack-y">Test Content</div>
</div>

Java Script:

$(document).ready(function () {
    var fResizeLayout = null;

    fResizeLayout = function() {
        var aFillElements = $('.fill-y');
        $.each(aFillElements, function (i, e) {
            var p = null,
                iPY = 0,
                iY = 0,
                iH = 0;
            e = $(e);
            p = e.parent();
            if (p.prop('tagName') === 'body') { iPY = $(window).height(); }
            else { iPY = p.innerHeight(); }
            e.siblings('.stack-y').each(function () {
                iY += $(this).outerHeight(true);
            });
            iH = (iPY - iY - parseInt(e.css('border-top-width'), 10) - parseInt(e.css('border-bottom-width'), 10));
            e.height(iH);
        });
        kendo.resize($('#content'));
    };

    kendo.init($('#content'));
    fResizeLayout();

    $(window).on('resize', function () {
        if (this.resizeTO) clearTimeout(this.resizeTO);
        this.resizeTO = setTimeout(function () {
            $(this).trigger('resizeEnd');
        }, 200);
    });

    $(window).on('resizeEnd', function () {
        fResizeLayout();
    });            
});

Of course you will need to include the kendo libraries for the kendo part to work.

<link href="http://cdn.kendostatic.com/2013.3.1119/styles/kendo.common.min.css" rel="stylesheet" type="text/css" />
<link href="http://cdn.kendostatic.com/2013.3.1119/styles/kendo.default.min.css" rel="stylesheet" type="text/css" />
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://cdn.kendostatic.com/2013.3.1119/js/kendo.all.min.js"></script>

Without the keno libraries:

HTML:

<div id="header" class="stack-y">header</div>
<div id="nav" class="stack-y">Nav</div>
<div id="title" class="stack-y">title</div>
<div id="content" class="fill-y">
    Test Fill Content
</div>
<div class="stack-y">Test Stacked Content</div>

Java Script:

$(document).ready(function () {
    var fResizeLayout = null;

    fResizeLayout = function() {
        var aFillElements = $('.fill-y');
        $.each(aFillElements, function (i, e) {
            var p = null,
                iPY = 0,
                iY = 0,
                iH = 0;
            e = $(e);
            p = e.parent();
            if (p.prop('tagName') === 'body') { iPY = $(window).height(); }
            else { iPY = p.innerHeight(); }
            e.siblings('.stack-y').each(function () {
                iY += $(this).outerHeight(true);
            });
            iH = (iPY - iY - parseInt(e.css('border-top-width'), 10) - parseInt(e.css('border-bottom-width'), 10));
            e.height(iH);
        });
    };

    fResizeLayout();

    $(window).on('resize', function () {
        if (this.resizeTO) clearTimeout(this.resizeTO);
        this.resizeTO = setTimeout(function () {
            $(this).trigger('resizeEnd');
        }, 200);
    });

    $(window).on('resizeEnd', function () {
        fResizeLayout();
    });            
});

Credit to Carlos for the resizeEnd part: https://stackoverflow.com/a/12692647/2109254

Thanks to all those that contributed.

Hopefully this can help someone else.

Regards,

Scott

Foi útil?

Solução

Edit

This will give exactly the layout you are looking for, using display:table-row in the wrapped content.

html {
    height:100%;
    padding: 0;
    margin: 0;
}
body {
    height: 100%;
    padding: 0;
    margin: 0;
}
#header {
    background-color:red;
    padding: 0;
    margin: 0;
    display: table-row;
    height:1px;
}
#nav {
    background-color:gray;
    padding: 0;
    margin: 0;
    display:table-row;
    height:1px;
}
#title {
    background-color:azure;
    padding: 0;
    margin: 0;
    display:table-row;
    height:1px;
}
#content {
    background:green;
    padding: 0;
    margin: 0;
    display:table-row;
}
#wrapper {height:100%;width:100%;margin:0;padding:0;display:table}



<div id="wrapper">    
    <div id="header">header</div>

    <div id="nav">Nav</div>
    <div id="title">title</div>
    <div id="content">
        Content
    </div>
</div>

Check your updated fiddle

You need a wrapper for the elements, depending on your specific layout you might want to play with table css attributes (display: table-row etc).

<div id="wrapper">    
    <div id="header">header</div>

    <div id="nav">Nav</div>
    <div id="title">title</div>
    <div id="content">
        Content
    </div>
</div>



html {
    height:100%;
    padding: 0;
    margin: 0;
}
body {
    height: 100%;
    padding: 0;
    margin: 0;
}
#header {
    background-color:red;
    padding: 0;
    margin: 0;
}
#nav {
    background-color:gray;
    padding: 0;
    margin: 0;
}
#title {
    background-color:azure;
    padding: 0;
    margin: 0;
}
#content {

    padding: 0;
    margin: 0;
}
#wrapper {height:100%;margin:0;padding:0;background-color:antiquewhite;}

Outras dicas

instead of using height:100% use height:auto..and it will work..:)

Think about what you are doing. you are telling content to be 100% of it's containing element. This would be body.

Thus, content will take up the size of the window, but you still have three other divs with height, thus total content size will = 100% (body size) + header + nav + title

If you want to fix this, you could simply make the inner contents add up to 100% and adjust the percentages to what you need. Take a look:

http://jsfiddle.net/9wABW/3/

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top