9

Is there a way a fixed positioned div can inherit the width of a parent?

I know fixed width is relative to the window's so this code doesn't work:

#wrapper{
        position: relative;
        width:500px;
        height: 20px;
        background-color: blue;
}

#header{
        position: fixed;
        width: 100%;
        height: 20px;
        background-color: rgba(255,0,0,0.5);
}
<div id="wrapper">
  #wrapper
        <div id="header">
          #header
        </div>
    </div>

    
Alaa Saleh
  • 177
  • 1
  • 2
  • 14

2 Answers2

11

Use the inherit value for the width property on the #header selector.

Why This Works

By specifying position: fixed to the #header element, the #header element's position is calculated with respect to the viewport as specified in the CSS2 specification:

http://www.w3.org/TR/2011/REC-CSS2-20110607/visuren.html#positioning-scheme

However, position: fixed does not change the DOM structure, which means that the #wrapper element is still the parent of the #header element. As a consequence, the #header can still inherit property values from its parent element, even though its position is determined with respect to the viewport.

Note also that if you specify a percentage value for the width, the fixed element will calculate the value based on the viewport, as stated in the specification. However, this does not pertain to width: inherit, which takes its value from the parent element, not the viewport.

See: http://www.w3.org/TR/2011/REC-CSS2-20110607/visudet.html#propdef-width

For example, if you added the color property to #wrapper, it would be inherited by #header.

The distinction is that the initial/default value for width is auto whereas for color it is inherit. To get the parent's with property, you need to specify width: inherit, not width: 100%;

Note: There is a subtle distinction between the parent element and the containing block. In most cases, the two are the same, but for fixed positioned elements, they are different.

#wrapper {
  position: relative;
  width: 500px;
  height: 20px;
  background-color: blue;
  color: white;  /* for demo */
}
#header {
  position: fixed;
  width: inherit;
  height: 20px;
  background-color: rgba(255, 0, 0, 0.5);
}
<div id="wrapper">
  #wrapper
  <div id="header">
    #header
  </div>
</div>
Marc Audet
  • 46,011
  • 11
  • 63
  • 83
  • @Morpheus Good question, I am looking up the CSS spec to figure out why it works, not obvious that it should. – Marc Audet Jan 16 '15 at 11:45
  • Remember to up vote the answer if it has helped you to solve your problem. Welcome to StackOverflow! – Marc Audet Jan 16 '15 at 12:58
  • @MarcAudet any findings? – Morpheus Jan 16 '15 at 13:17
  • @Morpheus I added more details to my original answer that may explain things more clearly. – Marc Audet Jan 16 '15 at 15:08
  • Just wow :) It does makes sense and it doesn't at the same time. if you set the width of the `wrapper` element to 50%, the `header` element will be wider by 8px, which comes from body margin. That just screwed my mind :D – Morpheus Jan 16 '15 at 15:35
  • @morpheus Good point. If you set a % width to the wrapper, then the header inherits the % value for the width. The header than uses the % value of the viewport (not the wrapper!). The viewport does not have the 8px margin. In contrast, the wrapper takes into account the 8px margin from the body to computer the final width value. A bit of mind bender! – Marc Audet Jan 16 '15 at 15:55
  • This answer is so great, thanks @Marc Audet! Any thoughts on how to handle this if the parent element is a flex item with `flex-grow: 1` to fill the remaining space? Posted a new question about this at http://stackoverflow.com/questions/34344623/fixed-position-element-inheriting-width-of-flex-item – jabram Dec 17 '15 at 21:34
0

Change

#wrapper{
    position: relative;
    width:500px;
}

to

#wrapper{
    position: absolute;
    width:500px;
}
scooterlord
  • 15,124
  • 11
  • 49
  • 68
laur
  • 500
  • 1
  • 9
  • 23
  • I know "absolute" will make it relative to the parent, but I need it to be fixed so it doesn't disappear as the user scrolls down. – Alaa Saleh Jan 16 '15 at 11:32