7

I have an HTML page with fixed height header and footer and a element in between.

I want the element to have always the total height of the screen (excluding the header and the footer). For example, let's say the total height of the screen is 1000px and each of the header/footer has fixed height of 60px --> the div element height should be 880px. Now, the challenge I have it to make it responsive (no matter what is the screen size, the behavior should be as described) WITHOUT using JavaScript/JQuery. CSS only.

I've started by using "height: 100%" but don't know how to proceed...

 <html>
    <head></head>
    <body>
      <header class="header">my header</header>
      <div class="content">content</div>
      <footer class="footer">my footer</footer>
    </body>
</html>

http://codepen.io/anon/pen/QbGZgL

Note: IE 10 should be supported as well...

I have considered flexbox, but didn't understand how exactly I can use it for my needs. Let's say I have some text and some images in the content of the page. I do not want a vertical scroller to appear when the screen is smaller, I want the whole content to shrink so it will fill the available height.

Does CSS3 viewport units: vh/vw/vmin/vmax can help me here?

Stickers
  • 75,527
  • 23
  • 147
  • 186
Tamar Cohen
  • 1,272
  • 2
  • 16
  • 28
  • Use media queries, the height 100% is a start, but think about small screens, resize your footer/push it downwards when users have smaller screens so the footer doesn't take away all the content's space – JordyvD May 27 '15 at 12:27
  • something like http://codepen.io/anon/pen/XbNxqR ? – ketan May 27 '15 at 12:29
  • What about the vh unit? http://snook.ca/archives/html_and_css/vm-vh-units? height: calc(100vh - 120px) would be your solution. – Douwe de Haan May 27 '15 at 12:29
  • Have you looked at the [flexbox](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes) CSS feature? This is partially supported on IE10, possibly enough for your needs. More details about that [here](http://stackoverflow.com/a/18019533/1927589) – James Newton May 27 '15 at 12:30

10 Answers10

6

This is a simple setup with what I think you want to accomplish. IE10 support is possible only you have to prefix / use old syntax for the flex property.

We have a wrapper element to which we say: you are now a flex element and your child elements can be flex(ible) elements with display: flex;

For the direction we use column, default is 'row' but we want them under each other.

Finally we define heights to the header and footer and so to the main element: you have the flex property '1'. Which will fill up the space that is left over between the elements.

body, html {
  height: 100%;
  margin: 0;
  padding: 0;
}
.wrapper {
  display: flex;
  height: 100%;
  flex-direction: column;
  -ms-flex-direction: column;
  background: red;
}

header {
  height: 100px;
  background: blue;
}

main {
  flex: 1;
  background: orange;
}

footer {
  height: 20px;
  background: yellow;
}
<div class="wrapper">
  <header>
    Header element
  </header>

  <main>
    <h1> Main</h1>
  </main>

  <footer>
    Footer  
  </footer>
</div>
richardj
  • 101
  • 6
1

You can use absolute positioning to achieve this.

Try the following

CSS

.content {
    position:absolute;
    top:100px; /* make this equal to the height of your header tag */
    bottom:100px; /* make this equal to the height of your footer tag */
    left:0;
    right:0;
}
header {
    height:100px;
    background:green;
}
footer {
    height:100px;
    position:absolute;
    bottom:0;
    left:0;
    right:0;
    background:red;
}
  1. Give your header a fixed height.

  2. Give your footer a fixed height and position:absolute with a bottom:0, left:0; and a right:0;.

  3. Make your content div position:absolute and give it a left:0; and a right:0;. Make the top position equal to the height of your header and the bottom position equal to the height of your footer.

http://jsfiddle.net/z4h64juf/1/

Hope that helps.

Jako Basson
  • 1,461
  • 12
  • 19
  • What do you mean by "Make the top position equal to the height of your header div and the bottom position equal to the height of your footer div." ? – Tamar Cohen May 27 '15 at 12:39
  • Please see the example http://jsfiddle.net/z4h64juf/1/. Lets say your header height is 100px make the top position 100px – Jako Basson May 27 '15 at 12:40
  • Yeah Just saw it. Thanks! – Tamar Cohen May 27 '15 at 12:41
  • Saw you are not using divs. But to explain, if you have a height of 100px on your header and a height of 200px on your footer, make the top position of your content 100px and the bottom position of your content 200px to make it fill the available space – Jako Basson May 27 '15 at 12:42
  • Let me know if you need more clarification, but this should solve your issue. – Jako Basson May 27 '15 at 12:51
  • Thank you very much! I will defiantly check it out! – Tamar Cohen May 27 '15 at 19:46
0

you can do this with css calc:

html,body{ height:100%; }
.content{
    height: calc(100% - 120px);
}

Of course, you have to change 120px for whatever is the sum of the footer and the header height. And don't forget about the vendor prefixes.

More info: https://developer.mozilla.org/es/docs/Web/CSS/calc

An advice: don't forget to use the units inside the () and don't forget to use spaces around the - + * signs or it won't work.

Vandervals
  • 5,774
  • 6
  • 48
  • 94
0

I recommend to you the Flexible Box Layout Module, which has good support in your case (IE10+). Many classic problems with CSS can be easily solved with it, take a look at the Solved by Flexbox list.

A simple approach to face your problem would be to following HTML:

<div class="container">
    <header>Header</header>
    <main>Page contents</main>
    <footer>Footer</footer>
</div>

With a simple CSS:

.container {
    display: flex;
    flex-direction: column;
    flex-wrap: wrap;
    justify-content: flex-start;
    align-content: stretch;
    align-items: stretch;
}

.container main {
    flex-grow: 1;
    flex-shrink: 0;
}

Pay attention that the spec has changed three times since 2009, so there are little differences in syntax and needs of vender prefixes. The links that I showed talk about it too. Of course, it doesn't matter if you choose to use autoprefixer.

Erick Petrucelli
  • 14,386
  • 8
  • 64
  • 84
  • I like the idea of implementing new techniques but I also must raise a flag concerning the use of flex modules. This is not compatible with old browsers (certainly not IE10 which ['only supports an old incompatible draft version of the specification'](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes?redirectlocale=en-US&redirectslug=CSS%2FTutorials%2FUsing_CSS_flexible_boxes)). I'm at work at the moment and can't provide any valuable solution to this. I just wanted to advice against relying to heavily on the flexbox module. – Kristofer Gisslén May 27 '15 at 13:48
  • Sure, I agree with you against relying to heavily on Flexbox if needed to support a wide range of browsers. But based on what the OP wants, the old draft supported by IE10 fully covers it. Also, Flexbox is already a recomendation on [HTML5Please](http://html5please.com/#flexbox). Personally I believe the time of moving to this direction has come. – Erick Petrucelli May 27 '15 at 14:17
0

Fix both header and footer using position:fixed; and for content use

padding: 60px 0;
height: 100%;
box-sizing: border-box;

http://codepen.io/anon/pen/xGRyNW

Arun Prakash
  • 160
  • 1
  • 9
0

* { padding: 0; margin: 0; }
body { height: 100%; width: 100%; position: absolute; }
header, footer { height: 50px; width: 100%; background: red; position: fixed; }
footer { bottom: 0; }
main { min-height: calc(100% - 100px); padding: 50px 0; overflow: auto; }
<header></header>
<main>
    <p>Hello1</p>
    <p>Hello2</p>
    <p>Hello3</p>
    <p>Hello4</p>
    <p>Hello5</p>
    <p>Hello6</p>
    <p>Hello7</p>
    <p>Hello8</p>
    <p>Hello9</p>
    <p>Hello10</p>
    <p>Hello11</p>
    <p>Hello12</p>
    <p>Hello13</p>
    <p>Hello14</p>
    <p>Hello15</p>
    <p>Hello16</p>
    <p>Hello17</p>
    <p>Hello18</p>
    <p>Hello19</p>
    <p>Hello20</p>
</main>
<footer></footer>
Trung Vu
  • 491
  • 4
  • 19
0

You need to use vh (viewport height). A height: 100vh; will cover the screen from top to bottom.

If you want to read more about other specific units, go here: https://developer.mozilla.org/en-US/docs/Web/CSS/length

Manny Alvarado
  • 1,135
  • 9
  • 14
-1

Using fixed values for header and footer is simple. Lets say you have a value of 60px to both header and footer and position them sticky (fixed) top and bottom, you have the following code:

.header {
    position: fixed;
    top: 0;
    right: 0;
    left: 0;
    height: 60px;
}
.footer {
    position: fixed;
    bottom: 0;
    right: 0;
    left: 0;
    height: 60px;
}
.content {
    position: absolute;
    top: 60px;
    bottom: 60px;
    left: 0;
    bottom: 0;
    /*Now, if you need your content to overflow properly when higher than the space provided by the screen you may add:
    overflow-y: scroll;
    and a scrollbar will show up
    */
}

If you need the header and footer as %, then you need to set the height of html and body to 100% and set the top and bottom for .content according to the respective % values. You may consider adding html and body in the first part of your css code, just to follow the cascading rule of your elements in the page. And body should be margin: 0;

Working with absolute and fixed positions and adding left: 0 and right: 0 to all your elements, you skip the width values.

An example with overflow is here: http://codepen.io/desginarti/pen/OVbBoe

designarti
  • 609
  • 1
  • 8
  • 18
-1

Here is a quick tip for creating responsive elements that retain their aspect ratio as they scale.

However, when we specify a padding-bottom value for the same element, the padding measurement is calculated relative to the element’s width:

.rect {
    width: 100%;
    height: 0;
    padding-bottom: 50%;
}

Correct aspect ratio

You will notice that I have set the element’s height property to 0, to ensure that the height of any child elements will not be added to the padding value when the visible height is calculated.

A note about child elements

If you also want to specify percentage based heights for a child element, you will need to assign an absolute or relative position value to both the parent and the child:

.rect {
    position: relative;
    width: 100%;
    height: 0;
    padding-bottom: 50%;
 }
.rect p {
    position: absolute;
    margin: 0;
    height: 100%;
    }

View A Demo

Jainik Patel
  • 2,284
  • 1
  • 15
  • 35
-1

Try this,

HTML

<div class="pagewidth">
    <header>
    </header>
    <section class="wrapper">
    </section>
    <footer>
    </footer>
</div>

CSS

html,body{
    height: 100%;
    background: black;
    margin:0;
    padding:0;
}
*{
   box-sizing: border-box;
}
.pagewidth{   
    position: relative;
    height: 100%;
    min-height:100%;
}
header{
    background: green;
    position: absolute;
    left:0;
    top:0;
    width:100%;
    height: 30px;
    z-index:2;
}
.wrapper{
    background: black;
    position: absolute;
    left:0;
    top:0;
    z-index:1;
    width:100%;
    height:100%;
    padding: 30px 0;
}
footer{
    background: blue;
    position: absolute;
    left:0;
    bottom:0;
    width:100%;
    height: 30px;
    z-index:2;
}

https://jsfiddle.net/rtwLe6zu/

Nitekurs
  • 441
  • 5
  • 11