0

I have a problem...In the following example i don't want that the div who is fixed get over the div with the background red.

Here is the example:

http://jsfiddle.net/HFjU6/3645/

 #fixedContainer
{
    background-color:#ddd;
  position: fixed;
  width: 200px;
  height: 100px;
  left: 50%;
  top: 0%;
  margin-left: -100px; /*half the width*/
}
  • 2
    There is nothing in either your fiddle or snippet that has a red background. If you want the fixed smaller box to go behind the large box, then put `z-index: -1;` on your `#fixedContainer`. – Tyler Roper Oct 14 '16 at 17:56
  • Change `z-index` stack context to a value lower than that of the red `
    `, which may have the default value `0`, or the other way around, give a higher `z-index` to your red element. Example: `.fixed { z-index: -1; }` **or** `.red{ z-index: 1; }`.
    – Ricky Ruiz Oct 14 '16 at 18:00
  • sorry...I have edited now u can see – Pablo Malynovytch Oct 14 '16 at 18:12
  • Unclear what you're asking. Based on main question... _`don't want that the div who is fixed get over the div`_ and your own comments in answers... _`..the fixed div it must be up of the red...`_ You contradict yourself. – gmo Oct 14 '16 at 18:31
  • what i mean is that i don't need to work with z-index...The div who is fixed when the background comes it has to stay in the grey background and dont get under THE RED BACKGROUND! Here is an example (i know it is absolute) when I like to be whe you scroll to the red background....http://jsfiddle.net/HFjU6/3650/ – Pablo Malynovytch Oct 14 '16 at 18:46
  • Still not clear.... that is exactly what your fiddle example does. Perhaps you prefer to post your question in the [Spanish SO](http://es.stackoverflow.com/). – gmo Oct 14 '16 at 19:40
  • why? i dont speak spanish....what u dont understand? – Pablo Malynovytch Oct 14 '16 at 19:45
  • I thought that being from Argentina would be easier to explain in Spanish. Forget this. Returning to the question, is not clear because the explanation you give about the desired behavior, is exactly what does the example you provide, so it is not clear what you really need. I advise you rephrase your question, attach an image if necessary, explain well what happens and what do you want to happen instead. Browser version, OS and so on. – gmo Oct 14 '16 at 19:51
  • I think I finally understood what OP is asking. He wants to fixed container to be sticky, but be confined to the boundaries of the grey container, such that when the red container scrolls into view it remains within the grey container and doesn't scroll further. Is this what you want @PabloMalynovytch? If so, you will need a JS-based solution—add the JavaScript tag if desired, and I'll update my answer. – Terry Oct 14 '16 at 22:49
  • Oh I see... probably you're right.. OP original fiddle is also here [fixed-position-but-relative-to-container](http://stackoverflow.com/questions/6794000/fixed-position-but-relative-to-container), so your guess looks right and make sense. – gmo Oct 16 '16 at 19:12
  • YES! @Terry thanks!( i don't i forget that) – Pablo Malynovytch Oct 17 '16 at 15:29
  • Are you willing to accept a jQuery-based answer? I see that you don't have the jQuery tag added, so I'm asking. – Terry Oct 17 '16 at 15:30
  • yes(I've just edit the tags) – Pablo Malynovytch Oct 17 '16 at 15:33

2 Answers2

1

Alright, I think I get what the OP wants. He wanted a container that stays fixed on the top of the viewport, but remains confined by a parent. This behaviour is known as a conditional sticky behaviour, and is actually implemented in both Firefox (without vendor prefix) and macOS/iOS Safari (with -webkit- prefix): see position: sticky.

Therefore the easiest (but also the least cross-browser compatible) way is simply to modify your markup, such that the sticky element stays within a parent, and you declare position: sticky on it:

* {
  margin: 0;
  padding: 0;
}
#fixedContainer {
  background-color: #ddd;
  position: -webkit-sticky;
  position: sticky;
  width: 200px;
  height: 100px;
  left: 50%;
  top: 0%;
  transform: translate(-50%, 0);  /* Negative left margins do not work with sticky */
}
#div1 {
  height: 200px;
  background-color: #bbb;
}
  #div1 .content {
    position: relative;
    top: -100px;  /* Top offset must be manually calculated */
    }
#div2 {
  height: 500px;
  background-color: red;
}
<div id="div1">
  <div id="fixedContainer">I am a sticky container that stays within the sticky parent</div>
  <div class="content">Sticky parent</div></div>
<div id="div2">Just another element</div>

An alternative would be to use a JS-based solution. In this case, you do not actually have to modify your markup. I have changed the IDs for easier identification of the elements, however.

The gist of the logic is this:

  • When the scroll position does not exceed the bottom of the parent minus the outer height of the sticky content, then we do not do anything.
  • When the scroll position exceeds the bottom of the parent minus the outer height of the sticky content, we dynamically calculate the top position of the sticky content so that it remains visually in the parent.

$(function() {
  $(window).scroll(function() {
    var $c = $('#sticky-container'),
      $s = $('#sticky-content'),
      $t = $(this); // Short reference to window object

    if ($t.scrollTop() > $c.outerHeight() - $s.outerHeight()) {
      $s.css('top', $c.offset().top + $c.outerHeight() - $t.scrollTop() - $s.outerHeight());
    } else {
      $s.css('top', 0);
    }
  });
});
* {
  margin: 0;
  padding: 0;
}
div {
  height: 500px;
  background-color: red;
}
#sticky-container {
  background-color: #bbb;
  height: 200px;
}
#sticky-content {
  background-color: #ddd;
  position: fixed;
  width: 200px;
  height: 100px;
  margin-left: -100px;
  left: 50%;
  top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="sticky-content">Sticky content that stays within the bounds of #div1</div>
<div id="sticky-container">Sticky confinement area</div>
<div>Other content</div>

Old answer before OP clarified the question appropriately:

Just give them the appropriate z-index values. In this case, you want to:

  1. Do not use static positioning. This can be done by using position: relative for the large elements, in conjunction with the originally position: fixed element.
  2. Assign the appropriate stacking order. The grey <div> element to have the lowest z-index, followed by the position fixed element, and then by the red element.

There are some catchalls to stacking though: the stacking context is reset when you traverse up or down the node tree. For example, the example will not work if the elements are not siblings.

Here is a proof-of-concept example, modified from your fiddle so that inline CSS is removed.

* {
  margin: 0;
  padding: 0;
}
#fixedContainer {
  background-color: #ddd;
  position: fixed;
  width: 200px;
  height: 100px;
  left: 50%;
  top: 0%;
  margin-left: -100px;
  z-index: 2;
}
#div1 {
  height: 200px;
  background-color: #bbb;
  position: relative;
  z-index: 1;
}
#div2 {
  height: 500px;
  background-color: red;
  position: relative;
  z-index: 3;
}
<div id="fixedContainer">z-index: 2</div>
<div id="div1">z-index: 1</div>
<div id="div2">z-index: 3</div>
Terry
  • 63,248
  • 15
  • 96
  • 118
  • Sorry that is not what i need...I know how to use z-index...te solution that i want is when the scroll cames to the background red..the fixed div it must be up of the red background and not be under the background...Also thank u! – Pablo Malynovytch Oct 14 '16 at 18:21
  • 2
    You need to phrase your question better: this is what you've said in your question "i don't want that the div who is fixed get over the div with the background red." If you want to achieve what is mentioned in your comment (fixed element stays on top of all elements), your Fiddle is already doing that. – Terry Oct 14 '16 at 18:24
  • Additionally if this is what you need, so, your code already do it! @PabloMalynovytch – SaidbakR Oct 14 '16 at 18:25
  • THANK U! That is exactly what i want.. :) – Pablo Malynovytch Oct 18 '16 at 13:28
-1

Just give the z-index.
Hope it helps...

http://jsfiddle.net/HFjU6/1/#run

#fixedContainer {
  background-color:#ddd;
  position: fixed;
  width: 200px;
  height: 100px;
  left: 50%;
  top: 0%;
  margin-left: -100px; /*half the width*/
  z-index: 2;
}

.div-red {
  position: relative;
  z-index: 5;
}
<div id="fixedContainer"></div>
<div style="height:200px;background-color:#bbb;"></div>
<div style="height:500px;background-color:red;" class="div-red"></div>
gmo
  • 8,860
  • 3
  • 40
  • 51
Gfie
  • 11
  • 1
  • 1