How can I make a fixed positioned div inherit width of parent?
Asked Answered
C

2

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>

    
Cheliform answered 16/1, 2015 at 11:27 Comment(0)
M
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>
Macula answered 16/1, 2015 at 11:33 Comment(7)
@Morpheus Good question, I am looking up the CSS spec to figure out why it works, not obvious that it should.Macula
Remember to up vote the answer if it has helped you to solve your problem. Welcome to StackOverflow!Macula
@MarcAudet any findings?Arnitaarno
@Arnitaarno I added more details to my original answer that may explain things more clearly.Macula
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 :DArnitaarno
@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!Macula
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 #34345123Lucifer
R
0

Change

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

to

#wrapper{
    position: absolute;
    width:500px;
}
Robles answered 16/1, 2015 at 11:29 Comment(1)
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.Cheliform

© 2022 - 2024 — McMap. All rights reserved.