1

Why does setting an element to be position:fixed change its width? I know that HTML elements by default span the entire width of the browser window, but when I set the position on my header to be fixed, the <div> shrinks to zero width. Why is this?

Trying width:auto does not fix it, the <div> still has zero width!

This example is taken from Code Academy "Build a Resume" project at the end of their Web Fundamentals course.

I have an HTML file like so:

    <!DOCTYPE html>
<html>
    <head>
        <link type="text/css" rel="stylesheet" href="stylesheet.css"/>
        <title></title>
    </head>
    <body>
        <div id="header"></div>
        <div class="left"></div>
        <div class="right"></div>
        <div id="footer"></div>
    </body>
</html>

and a CSS file like so:

    div {
    border: 5px solid red;
    border-radius: 5px;
}

#header{
    height:30px;
    background-color:orange;
    z-index:1;
}

#footer{
    height:30px;
    background-color:teal;
    clear:both;
}

.left{
    height:300px;
    width:200px;
    float:left;
}

.right{
    height:300px;
    width:200px;
    float:right;
}

UPDATE: I noticed that setting width:100% does keep the width all the way across the browser window. What is going on here? I've read Why does fixed positioning alter the width of an element? but am not sure how that applies here.

Edit: Thought I would move this up from the comments and try answering it here, to give more direction on where I'm confused: "Yes, it seems like "Whereas the position and dimensions of an element with position:absolute are relative to its containing block, the position and dimensions of an element with position:fixed are always relative to the initial containing block" is the key part. So I see that position:fixed will set the dimensions of my relative to the viewport, but isn't the viewport the whole browser window? So why does its size collapse to zero? And beyond that, why does width:auto not fix it but width:100% does make it span the whole horizontal length again?"

width:auto is different from width:100%. width:auto will expand the width of the element to all horizontal space within its containing block. Since the space is on the inside of the containing block it doesn't count borders/padding/margins.

width:100% does what width:auto does and adds the width of the borders/padding/margins of the containing element. difference between width auto and width 100 percent provides a good visual demonstration.

So, when I set width:auto on my position:fixed element, and the position:fixed shrink-wrapped the element's width to be that of its content (which was nothing), then the width automatically adjusted to be that of the containing element, which in this case was _________ (what? and why did it have a width of zero?).

When I set it to be width:100% then it includes the padding/margins/border of _________ (what? and why did it expand to cover the whole page horizontally?).

Community
  • 1
  • 1
phoenixdown
  • 828
  • 1
  • 10
  • 16
  • Did you read the [docs](http://www.w3.org/wiki/CSS_absolute_and_fixed_positioning#Fixed_positioning) from that question you referenced? – Last1Here Jun 19 '14 at 18:40
  • Yes, it seems like "Whereas the position and dimensions of an element with `position:absolute` are relative to its containing block, the position and dimensions of an element with `position:fixed` are always relative to the initial containing block" is the key part. So I see that `position:fixed` will set the dimensions of my `
    ` relative to the viewport, but isn't the viewport the whole browser window? So why does its size collapse to zero? And beyond that, why does `width:auto` not fix it but `width:100%` does make it span the whole horizontal length again?
    – phoenixdown Jun 19 '14 at 18:43
  • What you really need to read is http://www.w3.org/TR/CSS2/visudet.html#abs-non-replaced-width. What it says in brief, is that when left, width, and right are all "auto", the used width is shrink-to-fit. That's all you need to know. Whether it is in-flow or out-of-flow, relative to the viewport, the initial containing block, or anything else is irrelevant. – Alohci Jun 19 '14 at 20:39

2 Answers2

1

This is the default behavior.

Read http://www.w3.org/wiki/CSS_absolute_and_fixed_positioning#Specifying_dimensions

Absolutely positioned elements will shrink-wrap to fit their contents unless you specify their dimensions. You can specify the width by setting the left and right properties, or by setting the width property. You can specify the height by setting the top and bottom properties, or by setting the height property.

Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317
1

The reason is because both fixed and absolute positioning take the element out of the flow of the document. The residual effect of this is that, unless explicitly told otherwise, the element will now grow/shrink according to the size of its content rather than the size of its parent.

As you've already discovered, a simple fix is to give it a width of 100 percent:

.fixed-element{

  position:fixed;
  width:100%

}

To address the issue of the quote on fixed positioning:

Whereas the position and dimensions of an element with position:absolute are relative to its containing block, the position and dimensions of an element with position:fixed are always relative to the initial containing block. This is normally the viewport: the browser window or the paper’s page box.

I actually find it to be quite poorly worded. It's not meant to say that the dimensions will grow to the size of the viewport. Instead it's trying to distinguish the specific differences between absolute and fixed positioning. More thoroughly put: the dimensions/size of the fixed element will always be relative to the initial element. Whereas the dimensions/size of the absolute element will be relative to the containing element. That doesn't explicitly mean that it will actually take 100% of the viewport by default...

shennan
  • 10,798
  • 5
  • 44
  • 79
  • thanks this helped - i didn't realize taking an element out of the flow means it grows/shrinks with regards to its content instead of the size of the containing element. so `width:auto` here basically changed nothing about how the width was being calculated. since `width:100%` did work, what is it 100% of? – phoenixdown Jun 19 '14 at 18:56
  • evidently the viewport... that's exactly what is meant by "relative to" in the quote. It doesn't mean it will be the same size as it without being told, but it does mean that 100% is equal to it. Hence 100% = 100% width of viewport in this case. – shennan Jun 19 '14 at 19:03