208

I'm trying to give a div (position: fixed) the width of 100% (relating to it's parent div). But I've got some problems...

EDIT: The first problem is sovled by using inherit, but it still doesn't work. I think the problem is that I'm using multiple divs that take the 100%/inherit width. You can find the second problem on the jsfiddle update: http://jsfiddle.net/4bGqF/7/

Fox example

#container {
    width: 800px;
}

#fixed {
    position: fixed;
    width: 100%;
}

and the html

<div id="container">
    <div id="fixed">Sitename</div>
    <p>
        blaat
    </p>
</div>

Or you can try it out: http://jsfiddle.net/4bGqF/

The problems seems to be that the fixed element is always taking the width of the window/document. Does anyone know how the fix this?

I can't give my fixed element a fixed with, because I'm using the jScrollPane plugin. It depends on the content whether there's a scrollbar or not.

Thanks a lot!

PS: The text of the 2 divs are on top of each other. This is just an example so that doesn't really matter.

Hashem Qolami
  • 97,268
  • 26
  • 150
  • 164
Dnns
  • 2,614
  • 3
  • 18
  • 16
  • see my answer below which offers some additional insight into `inherit` and how using `max-width:inherit` with `width:inherit` keeps the container/contained ratio the same while still being responsive and manageable – aequalsb Apr 10 '17 at 18:51

11 Answers11

157

I´m not sure as to what the second problem is (based on your edit), but if you apply width:inherit to all inner divs, it works: http://jsfiddle.net/4bGqF/9/

You might want to look into a javascript solution for browsers that you need to support and that don´t support width:inherit

jeroen
  • 91,079
  • 21
  • 114
  • 132
98

fixed position is a bit tricky (indeed impossible), but position: sticky is doing the trick beautifully:

<div class='container'>
  <header>This is the header</header>
  <section>
    ... long lorem ipsum
  </section>
</div>


body {
  text-align: center;  
}

.container {
  text-align: left;
  max-width: 30%;
  margin: 0 auto;
}


header {
  line-height: 2rem;
  outline: 1px solid red;
  background: #fff;
  padding: 1rem;

  position: sticky;
  top: 0;
}

see the codepen sample

Multicam
  • 1,101
  • 7
  • 7
  • 5
    An FYI for anyone trying to do a sticky *footer*: It only works if it has a sibling element that comes after it. So just throw an empty div under it (you might have to give the bottom div a height). – Alex von Brandenfels Nov 15 '21 at 19:56
  • this works for me setting my nav to width=100% will not take up the whole screen size but rather relative to it's container. position: fixed; is not what I need on this one. – mike_s Jul 24 '23 at 04:43
69

As many people have commented, responsive design very often sets width by %

width:inherit will inherit the CSS width NOT the computed width -- Which means the child container inherits width:100%

But, I think, almost as often responsive design sets max-width too, therefore:

#container {
    width:100%;
    max-width:800px;
}
#contained {
    position:fixed;
    width:inherit;
    max-width:inherit;
}

This worked very satisfyingly to solve my problem of making a sticky menu be restrained to the original parent width whenever it got "stuck"

Both the parent and child will adhere to the width:100% if the viewport is less than the maximum width. Likewise, both will adhere to the max-width:800px when the viewport is wider.

It works with my already responsive theme in a way that I can alter the parent container without having to also alter the fixed child element -- elegant and flexible

ps: I personally think it does not matter one bit that IE6/7 do not use inherit

aequalsb
  • 3,765
  • 1
  • 20
  • 21
15

You can also solve it by jQuery:

var new_width = $('#container').width();
$('#fixed').width(new_width); 

This was so helpful to me because my layout was responsive, and the inherit solution wasn't working with me!

Hakan Fıstık
  • 16,800
  • 14
  • 110
  • 131
15

Use this CSS:

#container {
    width: 400px;
    border: 1px solid red;
}

#fixed {
    position: fixed;
    width: inherit;
    border: 1px solid green;
}

The #fixed element will inherit it's parent width, so it will be 100% of that.

banrobert
  • 404
  • 3
  • 8
  • 1
    except IE6-7 don't support `inherit`. Not sure if that mattesr. – Thomas Shields May 03 '11 at 18:04
  • Thanks a lot. It works when I try it in the example but not in my code... Anyway it's an answer to the question I asked here. There's probably another reason why it doesn't work... But still, thanks! – Dnns May 03 '11 at 18:10
  • 2
    Not working with block elements without explicitely set width – tylik Sep 09 '20 at 11:52
7

Fixed positioning is supposed to define everything in relation to the viewport, so position:fixed is always going to do that. Try using position:relative on the child div instead. (I realize you might need the fixed positioning for other reasons, but if so - you can't really make the width match it's parent with out JS without inherit)

Thomas Shields
  • 8,874
  • 5
  • 42
  • 77
  • 2
    @Downvoter - can you explain, please? I've no issue with a downvote but i like to know why so i can improve my answers in the future. – Thomas Shields May 03 '11 at 18:20
  • 1
    You're explanation is fine, however you said "you can't really make the width match it's parent without JS". Although it is possible in some cases (by using inherit). – Dnns May 03 '11 at 18:47
  • oh, of course. I'd forgotten about inherit as i target IE alot and only IE9+ supports it. – Thomas Shields May 03 '11 at 18:55
  • 1
    even Microsoft wants IE to disappear -- considering how old this original post is, i think it's safe to say the IE issue is moot. if strongly recommend not to support IE UNLESS you are billing specifically for such support -- and by the hour! – aequalsb Apr 10 '17 at 18:55
5

For sticky header with jquery, I am still a learner in jquery these css settings worked.

header.sticky{
    position: fixed;
    border-radius: 0px;
    max-height: 70px;
    z-index: 1000;
    width: 100%;
    max-width: inherit;
}

header is inside a wrapper div which is with max width of 1024.

Ahmet Emre Kilinc
  • 5,489
  • 12
  • 30
  • 42
Rabbani
  • 51
  • 1
  • 1
4

Here is a little hack that we ran across while fixing some redraw issues on a large app.

Use -webkit-transform: translateZ(0); on the parent. Of course this is specific to Chrome.

http://jsfiddle.net/senica/bCQEa/

-webkit-transform: translateZ(0);
Hakan Fıstık
  • 16,800
  • 14
  • 110
  • 131
Senica Gonzalez
  • 7,996
  • 16
  • 66
  • 108
  • 3
    This fixes the width problem, but it made the child un-fixed relative to the viewport. – V Maharajh Sep 13 '16 at 15:29
  • 1
    Sorry for the downvote, as this completely defeats the purpose of position:fixed. – trusktr Apr 20 '17 at 21:43
  • I don't think you read the question. It says, how do you make a div "relative" to a parent with "fixed" position. THAT TOO is anti-fixed position. And my response clearly says, "hack". It doesn't defeat the purpose when it gets you closer to you solution. – Senica Gonzalez Apr 20 '17 at 22:57
3

There is an easy solution for this.

I have used a fixed position for parent div and a max-width for the contents.

You don't need to think about too much about other containers because fixed position only relative to the browser window.

       .fixed{
            width:100%;
            position:fixed;
            height:100px;
            background: red;
        }

        .fixed .content{
            max-width: 500px;
            background:blue;
            margin: 0 auto;
            text-align: center;
            padding: 20px 0;
        }
<div class="fixed">
  <div class="content">
     This is my content
  </div>
</div>
2

This solution meets the following criteria

  1. Percentage width is allowed on parent
  2. Works after window resize
  3. Content underneath header is never inaccessible

As far as I'm aware, this criteria cannot be met without Javascript (unfortunately).

This solution uses jQuery, but could also be easily converted to vanilla JS:

function fixedHeader(){
  $(this).width($("#wrapper").width());
  $("#header-filler").height($("#header-fixed").outerHeight());
}

$(window).resize(function() {
  fixedHeader();
});

fixedHeader();
#header-fixed{
  position: fixed;
  background-color: white;
  top: 0;
}
#header-filler{
  width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
<div id="header-fixed">
  This is a nifty header! works even when resizing the window causing a line break
</div>
<div id="header-filler"></div>

[start fluff]<br>
a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>
a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>
a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>
[end fluff]

</div>
Skeets
  • 4,476
  • 2
  • 41
  • 67
1

You need to give the same style of the fixed element and its parent element. One of these examples is created with max widths and in the other example with paddings.

* {
  box-sizing: border-box
}
body {
  margin: 0;
}
.container {
  max-width: 500px;
  height: 100px;
  width: 100%;
  margin-left: auto;
  margin-right: auto;
  background-color: lightgray;
}
.content {
  max-width: 500px;
  width: 100%;
  position: fixed;
}
h2 {
  border: 1px dotted black;
  padding: 10px;
}
.container-2 {
  height: 100px;
  padding-left: 32px;
  padding-right: 32px;
  margin-top: 10px;
  background-color: lightgray;
}
.content-2 {
  width: 100%;
  position: fixed;
  left: 0;
  padding-left: 32px;
  padding-right: 32px;
}
<div class="container">
  <div class="content">
    <h2>container with max widths</h2>
  </div>
</div>

<div class="container-2">
  <div class="content-2">
    <div>
      <h2>container with paddings</h2>
    </div>
  </div>
</div>
desertnaut
  • 57,590
  • 26
  • 140
  • 166
Khachik
  • 71
  • 4