0

I have the following structure of HTML document:

<body>
    <header></header>
    <main class="page-main">
         <div>
              <aside></aside>
              <div class="page-content"></div>
         </div>
    </main>
    <footer class="page-footer"></footer>
</body>

And here are basic css rules:

html {
  height: 100%;
  width: 100%;
  position: relative;
}

body {
  padding-bottom: 256px;
  width: 100%;
  min-width: 1124px;
  min-height: 100%;
  position: relative;
}

.page-main {
    height: 100%;
}

.page-footer {
    position: absolute;
    background-color: #3D3D3D;
    bottom: 0;
    width: 100%;
    height: 256px;
 }

On desktops everything looks good, but on mobile devices if content of "main" tag is too short it doesn't take all available height and there is a blank space.

enter image description here

What is the best way to stretch "page-main" height to all available height?


UPD1

Please note, that I use min-height for "body" tag and set it to 100%. If I define "height" property for body and set it to 100% - problem with long content occur (see image below) enter image description here

UPD2

I created basic layout to explain my problem:

My goal is to make "aside" element to stretch to all available height of it's parent. I want to know if it's possible to do with my current layout?

  html{margin: 0px; padding: 0px; height: 100%;}
    body {margin: 0px;  background-color: pink; min-height: 100%; position: relative; }
    header {background-color: red; text-align: center;}
    main {height: 100%; padding-bottom: 100px;}
    footer {position: absolute; height: 100px; background-color: black; width: 100%; bottom: 0px; color: white; text-align: center}
    aside {float: left; width: 100px;  border-right: 3px #008000 solid; }
    .page-content {float: left;}
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <header>
        <div>Header1</div>
        <br>
        <div>Header2</div>
    </header>
    <main class="page-main">
        <div class="wrapper">
            <aside>
                <ul>
                    <li>Item 1</li>
                    <li>Item 2</li>
                    <li>Item 3</li>
                    <li>Item 4</li>
                </ul>
            </aside>
            <div class="page-content"> Lorem ipsum dolor sit  fdgk ;ldgk ;ldfkg ;krtj kljgf ;oitrji ojfglkh;j l;gfhj io
            </div>
        </div>

    </main>
    <footer>MY FOOTER</footer>
</body>
</html>
Tamara
  • 2,910
  • 6
  • 44
  • 73
  • 1
    We can't see your full code, or just even .page-main css so may be all you have to do is to give it a height of 100%. Mobile window is vertical-oriented so you just don't have enough content inside to stretch it. Give more source code. – Alex Bykov Nov 18 '15 at 20:49
  • Your problem is that you are using T-Mobile :) – Adam Buchanan Smith Nov 18 '15 at 20:58
  • @AlexBykov Thank you for response. I have added css rules for "page-main". I don't understand how to deal with situation when content is too short. How to stretch "page-main" just between header and footer? Will appreciate any advice. – Tamara Nov 18 '15 at 21:01
  • Examine codepen snippet I linked you and try to remove some contet - it will stay 100% *minimum* – Alex Bykov Nov 19 '15 at 00:20

3 Answers3

0
body, html, .page-main{
  height: 100%;
}

If your main does not have another parent besides body wrap it like this ^

Also, if you are bored with 100% parent hack go for 100vh;

also

if your content will stretch for more than 100% height (which is unlickely) you can wrap the content inside in another div with class named say .content and add this jquery:

$(document).ready(function() {
  $('.page-main').height($('.content').height());
});

this will update the height of your div only if content within exceeds 100% and fall back to 100% if it does not.

Codepen for you

Or, if you do not want to go for jquery — do it with flexbox Flexbox Complete Guide

Alex Bykov
  • 718
  • 6
  • 13
  • If I set height:100% for "body" tag I will have problem when content is bigger that browser window height. – Tamara Nov 18 '15 at 21:34
  • Please check UPD1 about long content. Thank you for js advice, but I'm sure it can be done in pure CSS. Could you provide more details about flexbox? Is it possible to stretch element to all available height with it? – Tamara Nov 19 '15 at 00:16
0

2 ways, CSS absolute positioning, or via JavaScript. Since you provided CSS I shall give you my CSS version. I see you are using height: 100%; on the body and html, so you will need to specify heights for the containing divs (according to your example):

.page-main {
   height: 100%;
   position: relative;
}
aside {
  height:100%;
}

Assuming aside is where your box shadow is.

This may however cause a problem. Your footer is position: absolute; and bottom:0; whereas everything else is not absolute. So you may find some overlapping here. This will also explain the gap you are having. Really you should remove these styles.

[Update: JavaScript Solution]

Remove position:absolute from the footer, this will cause content overlapping in this case, especially in a responsive nature. This should eliminate the gap issue you see between the content and the footer.

A new problem will emerge, the footer will no longer be at the bottom of page unless the content stretches further than the height of the screen. because of this we need to use JavaScript to dynamically push the main content down. I will wrap this in a de-bouncer function so it works on resize:

function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
}; 

// Give your elements IDs for this to work
var pushContent = debounce(function() {
    var header = document.getElementById('header');
    var main = document.getElementById('main');
    var footer = document.getElementById('footer');
    var winHeight = window.innerHeight;
    var contentHeight = header.outerHeight + main.outerHeight + footer.outerHeight;

    if (contentHeight < winHeight) {
       var h = winHeight - header.outerHeight - footer.outerHeight;
       main.setAttribute('style', 'height:' + h + 'px;')
    }

}, 250);

window.addEventListener('resize', pushContent);
window.addEventListener('onload', pushContent);

This should work on load and on resize with a debouncer to try and keep browser efficiency up. Then it will calculate the height and attempt to push the main container height to always keep the footer at the bottom of the screen. Let me know if this works, I haven't tested it.

Chris Rogers
  • 1,525
  • 2
  • 20
  • 40
  • Thank you for answer, but I use "min-height" not "height" for body tag. I have followed this advice - http://stackoverflow.com/questions/6654958/make-body-have-100-of-the-browser-height – Tamara Nov 18 '15 at 23:48
  • Great, but what about the footer which is position absolute? – Chris Rogers Nov 19 '15 at 08:51
  • Yes, footer is absolute, but I'm open to any other ideas how to stick it to the bottom :) Please remember that content can be shorter or bigger than browser windows. – Tamara Nov 19 '15 at 18:45
  • I've revised my answer – Chris Rogers Nov 20 '15 at 13:27
0

You might be able to get what you're after by using the CSS display property to emulate table behavior...

html{margin: 0px; padding: 0px; height: 100%;}
body {display: table; margin: 0px; background-color: pink; width: 100%; height: 100%;}
header {display: table-row; background-color: red; text-align: center;}
main {display: table-row; height: 100%;}
footer {display: table-row; height: 100px; background-color: black; color: white; text-align: center}
aside {display: table-cell; width: 100px; border-right: 3px #008000 solid;}
.wrapper {display: table; width: 100%; height: 100%;}
.page-content {display: table-cell;}
<header>
  <div>Header1</div>
  <br>
  <div>Header2</div>
</header>
<main class="page-main">
  <div class="wrapper">
    <aside>
      <ul>
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
        <li>Item 4</li>
      </ul>
    </aside>
    <div class="page-content"> Lorem ipsum dolor sit  fdgk ;ldgk ;ldfkg ;krtj kljgf ;oitrji ojfglkh;j l;gfhj io
    </div>
  </div>
</main>
<footer>MY FOOTER</footer>
DoctorDestructo
  • 4,166
  • 25
  • 43