[html] position fixed is not working

I have the following html...

<div class="header"></div>
<div class="main"></div>
<div class="footer"></div>

And following css...

.header{
position: fixed;
background-color: #f00;
height: 100px;
}
.main{
background-color: #ff0;
height: 700px;
}
.footer{
position: fixed;
bottom: 0;
background-color: #f0f;
height: 120px;}

But why the header and footer is not fixed, anything I did wrong? I want only "main" to be scrollable and "header" and "footer" to be at a fixed position. How to do?

+-------------------------------------+
|     header                          |  -> at fixed position (top of window)
+-------------------------------------+
|       main                          |
|                                     |
|                                     | -> scrollable as its contents
|                                     |    scroll bar is window scroll bar not of main
|                                     |
|                                     |
+-------------------------------------+
|         footer                      |  -> at fixed position (bottom of window)
+-------------------------------------+

See this fiddle

This question is related to html css

The answer is


This might be an old topic but in my case it was the layout value of css contain property of the parent element that was causing the issue. I am using a framework for hybrid mobile that use this contain property in most of their component.

For example:

.parentEl {
    contain: size style layout;
}
.parentEl .childEl {
    position: fixed;
    top: 0;
    left: 0;
}

Just remove the layout value of contain property and the fixed content should work!

.parentEl {
    contain: size style;
}

Double-check that you haven't enabled backface-visibility on any of the containing elements, as that will wreck position: fixed. For me, I was using a CSS3 animation library...


You didn't add any width or content to the elements. Also you should set padding top and bottom to your main element so the content is not hidden behind the header/footer. You can remove the height as well and let the browser decide based on the content.

http://jsfiddle.net/BrmGr/12/

.header{
position: fixed;
background-color: #f00;
height: 100px;
    width:100%;
}
.main{
background-color: #ff0;
    padding-top: 100px;
    padding-bottom: 120px;
}
.footer{
position: fixed;
bottom: 0;
background-color: #f0f;
height: 120px;
    width:100%;}

You have no width set and there is not content in the divs is one issue. The other is that the way html works... when all three of fixed, is that the hierarchy goes from bottom to top... so the content is on top of the header since they are both fixed... so in this case you need to declare a z-index on the header... but I wouldn't do that... leave that one relative so it can scroll normally.

Go mobile first on this... FIDDLE HERE

HTML

<header class="global-header">HEADER</header>

<section class="main-content">CONTENT</section>

<footer class="global-footer">FOOTER</footer>

CSS html, body { padding: 0; margin: 0; height: 100%; }

.global-header {
    width: 100%;
    float: left;
    min-height: 5em;
    background-color: red;
}

.main-content {
    width: 100%;
    float: left;
    height: 50em;
    background-color: yellow;
}

.global-footer {
    width: 100%;
    float: left;
    min-height: 5em;
    background-color: lightblue;
}

@media (min-width: 30em) {

    .global-header {
        position: fixed;
        top: 0;
        left: 0;
    }

    .main-content {
        height: 100%;
        margin-top: 5em; /* to offset header */
    }

    .global-footer {
        position: fixed;
        bottom: 0;
        left: 0;
    }

} /* ================== */

if a parent container contains transform this could happen. try commenting them

-webkit-transform: translate3d(0,0,0);
transform: translate3d(0,0,0);

Working jsFiddle Demo

When you are working with fixed or absolute values, it's good idea to set top or bottom and left or right (or combination of them) properties.

Also don't set the height of main element (let browser set the height of it with setting top and bottom properties).

.header{
    position: fixed;
    background-color: #f00;
    height: 100px;
    top: 0;
    left: 0;
    right: 0;
}
.main{
    background-color: #ff0;
    position: fixed;
    bottom: 120px;
    left: 0;
    right: 0;
    top: 100px;
    overflow: auto;
}
.footer{
    position: fixed;
    bottom: 0;
    background-color: #f0f;
    height: 120px;
    bottom: 0;
    left: 0;
    right: 0;
}

You forgot to add the width of the two divs.

.header {
    position: fixed;
    top:0;
    background-color: #f00;
    height: 100px; width: 100%;
}
.footer {
    position: fixed;
    bottom: 0;
    background-color: #f0f;
    height: 120px; width:100%;
}

demo


We'll never convince people to leave IE6 if we keep striving to deliver quality websites to those users.

Only IE7+ understood "position: fixed".

https://developer.mozilla.org/en-US/docs/Web/CSS/position

So you're out of luck for IE6. To get the footer semi-sticky try this:

.main {
  min-height: 100%;
  margin-bottom: -60px;
}
.footer {
  height: 60px;
}

You could also use an iFrame maybe.

This will keep the footer from 'lifting off' from the bottom of the page. If you have more than one page of content then it will push down out of site.

On a philosophical note, I'd rather point IE6 users to http://browsehappy.com/ and spend the time I save hacking for IE6 on something else.


Another cause could be a parent container that contains the CSS animation property. That's what it was for me.


My issue was that a parent element had transform: scale(1); this apparently makes it impossible for any element to be fixed inside it. By removing that everything works normally...

It seems to be like this in all browsers I tested (Chrome, Safari) so don't know if it comes from some strange web standard.

(It's a popup that goes from scale(0) to scale(1))


I had a similar problem caused by the addition of a CSS value for perspective in the body CSS

body { perspective: 1200px; }

Killed

#mainNav { position: fixed; }