Set width of a "Position: fixed" div relative to parent div
Asked Answered
D

11

221

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.

Discuss answered 3/5, 2011 at 17:51 Comment(1)
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 manageableMahican
P
165

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

Penult answered 3/5, 2011 at 19:2 Comment(12)
Hehe thanks, I tried it in the JSfiddle (as you can see). But I thought the fixed div already had the 'inherit' property. My badDiscuss
+1 for a fantastically simple solution, although width: inherit isn't the first thing I would've thought ofWoodcutter
Any idea how to solve this if #container width is 50% inside a div with width = 100px (then container width would be 50px and fixed width would be 50% of browser width) ?Women
The trick with inheriting parent's width only works if the parent has a set width in px.Rascally
@Rascally - That's a HEAVY "trick". Most responsive websites heavily use % widths.Jobbery
This is a pretty bad answer... It's basically the equivalent of setting constant values, which isn't very useful at all.Expensive
How solve this if the container is using width in %?Booboo
please see my answer further down using inherit on BOTH width (in %) and max-width (in px)Mahican
How will it work when the parent is using percentage width?Earleanearleen
Worked for me. But I also had to do a max-width:100vw for it to work on mobiles and tablets at least in my case. But just the width:inherit; worked directly for laptops and bigger screens.Continuate
this doesn't work if the parent has relative withChapel
@Chapel Correct, but that is not the case here...Penult
S
106

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

Secco answered 17/5, 2019 at 5:11 Comment(2)
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).Neutrophil
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.Bringingup
M
72

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

Mahican answered 15/8, 2016 at 22:49 Comment(2)
Great answer! In my case, adding a min-width: inherit did the trick.Wace
This works for parent elements with widths defined as px and percentage. Should be the correct answer in my view.Virgenvirgie
P
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.

Peluso answered 3/5, 2011 at 17:57 Comment(3)
except IE6-7 don't support inherit. Not sure if that mattesr.Monopode
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!Discuss
Not working with block elements without explicitely set widthClinch
A
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!

Attenuator answered 26/1, 2014 at 12:29 Comment(4)
bad answer, if you resize the window this breaks.Expensive
Should really have a window.onresize event handler.Castellatus
This is the way to do. Could be wrapped into a function setWidth(), then call it on the "load" and "resize" window event listenersChafer
This worked well for me! I ran into an issue where the parent was width: 25%, so doing width: inherit made each child width: 25%.Commend
M
8

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)

Monopode answered 3/5, 2011 at 17:58 Comment(4)
@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.Monopode
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).Discuss
oh, of course. I'd forgotten about inherit as i target IE alot and only IE9+ supports it.Monopode
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!Mahican
E
5

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);
Embowel answered 28/1, 2014 at 22:25 Comment(3)
This fixes the width problem, but it made the child un-fixed relative to the viewport.Doncaster
Sorry for the downvote, as this completely defeats the purpose of position:fixed.Eradicate
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.Embowel
T
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.

Tiv answered 2/5, 2021 at 3:59 Comment(0)
O
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>
Officious answered 14/7, 2017 at 5:14 Comment(0)
C
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>
Cchaddie answered 10/9, 2018 at 10:0 Comment(0)
S
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>
Seavir answered 12/6, 2020 at 12:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.