简体   繁体   中英

How to make a div responsive height between header and footer with CSS only?

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?

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>

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.

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.

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 sintax 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 .

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

 * { 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>

Approach 1: The flexbox solution, works for both known/unknown height of header and footer. Browser support: IE10+

JsFiddle Demo

 html { height: 100%; } body { margin: 0; min-height: 100%; display: -ms-flexbox; /* IE 10 */ display: -webkit-flex; /* Safari */ display: flex; -ms-flex-direction: column; -webkit-flex-direction: column; flex-direction: column; } main { -ms-flex: 1; /* IE 10 */ -webkit-flex: 1; /* Safari */ flex: 1; background: lightgoldenrodyellow; } header, footer { background: lightseagreen; } 
 <header>header</header> <main>main</main> <footer>footer</footer> 

Approach 2: The CSS table solution, works for both known/unknown height of header and footer. Browser support: IE8+

JsFiddle Demo

 html, body { height: 100%; } body { display: table; width: 100%; margin: 0; } .header, .main, .footer { display: table-row; } .header, .footer { background: lightseagreen; } .main { height: 100%; background: lightgoldenrodyellow; } 
 <div class="header">header</div> <div class="main">main</div> <div class="footer">footer</div> 

Approach 3: The position solution, works only for known height of header and footer. Browser support: IE7+

JsFiddle Demo

 html { position: relative; min-height: 100%; } body { background: lightgoldenrodyellow; margin: 20px 0; } .header, .footer { background: lightseagreen; position: absolute; left: 0; width: 100%; height: 20px; } .header { top: 0; } .footer { bottom: 0; } 
 <div class="header">header</div> <div class="main">main</div> <div class="footer">footer</div> 

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

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

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

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/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM