Gavin Wood
Gavin Wood

Reputation: 1006

Fixed positioned div within a relative parent div

I am currently building a responsive website and need a menu to be fixed, thus not scrolling when the rest of the site scrolls. the issue is that it is a fluid layout and i want the "fixed positioned" menu item to be fixed relative to the containing parent element and not to browser window. is there anyway this can be done?

Upvotes: 35

Views: 144566

Answers (11)

Lohit Bisen
Lohit Bisen

Reputation: 157

Try position:sticky; on the parent element.

Upvotes: 11

Tadele Ayelegn
Tadele Ayelegn

Reputation: 4706

If you would like to have one of the div appear to be fixed while the other sibling div to be scrollable agains parent div(like side navigation bar and content area), here is one way to achieve it.

<div class="parent__div">
   <div class="fixed__div">

   </div>
   <div class="non__fixed-scrollable-div">

   </div>
</div>

.parent__div {
  display: grid;
  grid-template-columns: 1fr 10fr;
  overflow-y: hidden;
  height: 100vh;
}

.fixed__div {
  background: white;
  height: 100vh;
  overflow-y: auto;
}
.non__fixed-scrollable-div{
  height: 100vh;
  overflow-y: auto;
}

Upvotes: 0

Mohamad Hendy
Mohamad Hendy

Reputation: 51

justy change position from fixed to sticky

position: sticky

Upvotes: 1

KernelDeimos
KernelDeimos

Reputation: 617

An easy solution that doesn't involve resorting to JavaScript and will not break CSS transforms is to simply have a non-scrolling element, the same size as your scrolling element, absolute-positioned over it.

The basic HTML structure would be

CSS

<style>
    .parent-to-position-by {
        position: relative;
        top: 40px; /* just to show it's relative positioned */
    }
    .scrolling-contents {
        display: inline-block;
        width: 100%;
        height: 200px;
        line-height: 20px;
        white-space: nowrap;
        background-color: #CCC;
        overflow: scroll;
    }
    .fixed-elements {
        display: inline-block;
        position: absolute;
        top: 0;
        left: 0;
    }
    .fixed {
        position: absolute; /* effectively fixed */
        top: 20px;
        left: 20px;
        background-color: #F00;
        width: 200px;
        height: 20px;
    }
</style>

HTML

<div class="parent-to-position-by">
    <div class="fixed-elements">
        <div class="fixed">
            I am &quot;fixed positioned&quot;
        </div>
    </div>
    <div class="scrolling-contents">
        Lots of contents which may be scrolled.
    </div>
</div>
  • parent-to-position-by would be the relative div to position something fixed with respect to.
  • scrolling-contents would span the size of this div and contain its main contents
  • fixed-elements is just an absolute-positioned div spanning the same space over top of the scrolling-contents div.
  • by absolute-positioning the div with the fixed class, it achieves the same effect as if it were fixed-positioned with respect to the parent div. (or the scrolling contents, as they span that full space)

Here's a js-fiddle with a working example

Upvotes: 7

Fely Spring
Fely Spring

Reputation: 21

Sample solution. Check, if this is what you need.

<div class="container">
   <div class="relative">      
      <div class="absolute"></div>      
      <div class="content">
        <p>
          Content here
        </p>
      </div>
    </div>
 </div>

And for CSS

.relative { 
  position: relative;
}

.absolute {
  position: absolute;
  top: 15px;
  left: 25px;   
}

See it on codepen https://codepen.io/FelySpring/pen/jXENXY

Upvotes: 1

Mandar Kawtakwar
Mandar Kawtakwar

Reputation: 107

you can fix the wrapper using absolute positioning. and the give inside div a fixed position.

.wrapper{
 position:absolute;
 left:10%;// or some valve in px
 top:10%; // or some valve in px
 }

and div inside that

.wrapper .fixed-element{ 
position:fixed;
width:100%;
height:100%;
margin-left:auto; // to center this div inside at center give auto margin
margin-right:auto;
}

try this It might work for you

Upvotes: 1

afable
afable

Reputation: 185

A simple thing you can do is position your fixed DIV relative to the rest of your page with % values.

Check out this jsfiddle here where the fixed DIV is a sidebar.

div#wrapper {
    margin: auto;
    width: 80%;
}

div#main {
    width: 60%;
}

div#sidebar {
    position: fixed;
    width: 30%;
    left: 60%;
}

And a brief picture below describing the layout above:

example layout

Upvotes: 2

Leo
Leo

Reputation: 349

This question came first on Google although an old one so I'm posting the working answer I found, which can be of use to someone else.

This requires 3 divs including the fixed div.

HTML

<div class="wrapper">
    <div class="parent">
        <div class="child"></div>
    </div>
</div>

CSS

.wrapper { position:relative; width:1280px; }
    .parent { position:absolute; }
        .child { position:fixed; width:960px; }

Upvotes: 24

avrahamcool
avrahamcool

Reputation: 14094

here is a more generic solution, that don't depends on the Menu/Header height. its fully responsive, Pure CSS solution, Works great on IE8+, Firefox, Chrome, Safari, opera. supports Content scrolling without affecting the Menu/Header.

Test it with that Working Fiddle

The Html:

<div class="Container">
    <div class="First">
        <p>The First div height is not fixed</p>
        <p>This Layout has been tested on: IE10, IE9, IE8, FireFox, Chrome, Safari, using Pure CSS 2.1 only</p>
    </div>
    <div class="Second">
        <div class="Wrapper">
            <div class="Centered">
                <p>The Second div should always span the available Container space.</p>
                <p>This content is vertically Centered.</p>
            </div>
        </div>
    </div>
</div>

The CSS:

*
{
    margin: 0;
    padding: 0;
}

html, body, .Container
{
    height: 100%;
}

    .Container:before
    {
        content: '';
        height: 100%;
        float: left;
    }

.First
{
    /*for demonstration only*/
    background-color: #bf5b5b;
}

.Second
{
    position: relative;
    z-index: 1;
    /*for demonstration only*/
    background-color: #6ea364;
}

    .Second:after
    {
        content: '';
        clear: both;
        display: block;
    }

/*This part his relevant only for Vertically centering*/
.Wrapper
{
    position: absolute;
    width: 100%;
    height: 100%;
    overflow: auto;
}
    .Wrapper:before
    {
        content: '';
        display: inline-block;
        vertical-align: middle;
        height: 100%;
    }

.Centered
{
    display: inline-block;
    vertical-align: middle;
}

Upvotes: 1

Fuzzical Logic
Fuzzical Logic

Reputation: 13015

Gavin,

The issue you are having is a misunderstanding of positioning. If you want it to be "fixed" relative to the parent, then you really want your #fixed to be position:absolute which will update its position relative to the parent.

This question fully describes positioning types and how to use them effectively.

In summary, your CSS should be

#wrap{ 
    position:relative;
}
#fixed{ 
    position:absolute;
    top:30px;
    left:40px;
}

Upvotes: 14

JCOC611
JCOC611

Reputation: 19709

This is possible if you move the fixed <div> using margins and not positions:

#wrap{ position:absolute;left:100px;top:100px; }
#fixed{ 
   position:fixed;
   width:10px;
   height:10px;
   background-color:#333;
   margin-left:200px;
   margin-top:200px;
}

And this HTML:

<div id="wrap">
   <div id="fixed"></div>
</div>

Play around with this jsfiddle.

Upvotes: 3

Related Questions