Why isn't my margin working with position: fixed?
Asked Answered
I

5

30

JSFiddle Demo

I have a div for a header and a div for a content wrap.

For some reason, I can't have a margin on the bottom of the header that forces the content wrap to push down. It just ignores it completely and I have no idea why.

Does anyone know what is going on with this? It doesn't do this when I take away the position: fixed; attribute on the header, but I want it to be fixed at the top so when scrolling the header is always in view.

Hoping someone can explain why this happens or at least what it is called so I can google it.

body {
    margin: 0;
    padding: 0;
	font-family: arial;
	background: #5A9910;
	text-align: center;
}

/* ==========================Main wrap for page==*/
div.wrap {
	width: 100%;
	margin: 0 auto;
	text-align: left;
}

/* ==========================Header with logo==*/
div.header {
	position: fixed;
	width: 100%;
	background: #ffffff;
	-webkit-box-shadow: 0 8px 6px -6px #333;
	-moz-box-shadow: 0 8px 6px -6px #333;
	box-shadow: 0 8px 6px -6px #333;
}

/* ==========================Header logo image==*/
img.headerlogo {
	width: 30%;
}

/* ==========================Content wrapper==*/
div.contentwrap {
	width: 80%;
	height: 1600px;
	background: #ccc;
	margin: 0 auto;
}
<div class="wrap">
    <div class="header">
        <p>Header</p>
    </div>
    <div class="contentwrap">
        <p>Test</p>
    </div>
</div>
Inflationism answered 14/10, 2015 at 18:9 Comment(0)
G
13

i think you have to explictly declare the position of fixed div.

div.header {
position: fixed;
width: 100%;
background: #ffffff;
top:20px;
-webkit-box-shadow: 0 8px 6px -6px #333;
-moz-box-shadow: 0 8px 6px -6px #333;
box-shadow: 0 8px 6px -6px #333;
}

and assign margin at the content div

div.contentwrap {
width: 80%;
height: 1600px;
background: #ccc;
margin: 80px auto;
}

check this fiddle if works like you need: https://jsfiddle.net/0cmvg92m/3/

Guerdon answered 14/10, 2015 at 18:20 Comment(0)
P
140

When you set an element to position: fixed;, you remove it from the "normal document flow". Imagine your website is a river, and you're looking down at it from above. Each element is a rock in that river. Any margin you've applied to your elements is like a force field around one of those rocks.

When you set position: fixed; on one of those rocks, you're essentially pulling it up out of the river so that the rock, in essence, is floating above the river in midair. The rock and the river's flow of water will still look the same to you, because you're up above looking straight down, but the rock is no longer interacting with the river's flow.

If you had applied margin to that rock, that force field around the rock is no longer keeping any water away from it, because the rock is hovering in midair thanks to its position: fixed; property. So there's no water or other rocks (other elements) from which it needs to distance itself. Your rock's force field (your element's margin) is pushing against thin air, so nothing in the river will be affected.

But a picture is worth a thousand words, as the saying goes:

Kicking the Tower of Pisa

This man is not really kicking over the Leaning Tower of Pisa, but it sure looks like it! In this example, the background of the picture, including the Leaning Tower of Pisa, is your page (or your 'normal document flow'), and the man is an element (or the rock from our last example) with position: fixed; applied.

Read more about the position property here and, more up-to-date, here.

One way to fix this is to set your header to top: 20px; z-index: 2; to make sure it's positioned at the top and above every other element on the z-plane, and then give your body position: relative; and a margin-top equal to the height of the header (in this case, 52px) plus the value of the header's top property. To increase the space between your header and your body, just increase the margin-top amount. This is sometimes called the "sticky header/footer" approach. Here's a demo:

body {
    margin: 0;
    padding: 0;
    font-family: arial;
    background: #5A9910;
    text-align: center;
}

/* ==========================Main wrap for page==*/
div.wrap {
    width: 100%;
    margin: 0 auto;
    text-align: left;
}

/* ==========================Header with logo==*/
div.header {
    position: fixed;
    top: 20px;
    z-index: 2;
    width: 100%;
    background: #ffffff;
    -webkit-box-shadow: 0 8px 6px -6px #333;
    -moz-box-shadow: 0 8px 6px -6px #333;
    box-shadow: 0 8px 6px -6px #333;
}

/* ==========================Header logo image==*/
img.headerlogo {
    width: 30%;
}

/* ==========================Content wrapper==*/
div.contentwrap {
    width: 80%;
    height: 1600px;
    background: #ccc;
    margin: 0 auto;
    position: relative;
    margin-top: 72px;
}
<div class="wrap">
    <div class="header">
        <p>Header</p>
    </div>
    <div class="contentwrap">
        <p>Test</p>
    </div>
</div>

P.S. position: fixed; is a CSS property (a property-value pair, to be precise), not an HTML attribute.

Polytechnic answered 14/10, 2015 at 18:19 Comment(2)
write a book on cssKellikellia
I agree with ik00ma. This is the best explanation of how HTML/CSS works that I've ever read.Eliseo
G
13

i think you have to explictly declare the position of fixed div.

div.header {
position: fixed;
width: 100%;
background: #ffffff;
top:20px;
-webkit-box-shadow: 0 8px 6px -6px #333;
-moz-box-shadow: 0 8px 6px -6px #333;
box-shadow: 0 8px 6px -6px #333;
}

and assign margin at the content div

div.contentwrap {
width: 80%;
height: 1600px;
background: #ccc;
margin: 80px auto;
}

check this fiddle if works like you need: https://jsfiddle.net/0cmvg92m/3/

Guerdon answered 14/10, 2015 at 18:20 Comment(0)
G
0

Margin does not work because position of the header is fixed.

You have to use padding-top on your contentwrap.

Garcon answered 14/10, 2015 at 18:17 Comment(0)
S
0

Your header have property position:fixed. Hence the margin that you apply to header does not impact the content section.

To solve this problem, you need to give either margin or padding to the contentwrap element

Scissel answered 14/10, 2015 at 18:17 Comment(1)
That's not true. The contentwrap element does not control the header. The parent does: wrapAbseil
U
-4

the css that worked with me is

#toaster-container {
  width: 99%;
  height: 98%;
  margin: 15px;
  position: fixed;
  top: 0;
}

but I'm not sure how that worked, and don't know if it will still work with zooming

one more thing, the above css make width as the whole screen (100%). maybe that break some usages of top, bottom, right and left properties

Umpteen answered 3/12, 2018 at 14:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.