1

Say I have three divs like following:

<div class="wrapper"> <div class="container"> container1 <div class="element"> fixed </div> </div> <div class="container2"> container2 </div> </div> 

I want div: element to be fixed when it is inside div: container, but its position should become absolute when div: container2 becomes visible, it should not overlap with div - container2, but scroll away at that time with div: container.

A pure CSS solution is preferable, but if not possible I may go for a JS or jquery solution. I have created a fiddle for this, and tried some solution suggested here, which are not working.

2
  • Do you want to fix that fixed div to the first container? Commented Dec 29, 2016 at 8:41
  • @aavrug Yes, I want it to be fixed in first container, when second container comes I want this to scroll up and not have this in view. Commented Dec 29, 2016 at 9:44

4 Answers 4

1

What I would suggest is to use javascript to recognize when the scrolling is at a certain point with window.pageYOffset

When it reaches your desired window Y Offset you can start an event that modifies the css value of the positioning from fixed to absolute (by setting the parent container to relative) and bottom at 0.

Check out this jsfiddle https://jsfiddle.net/zq0kkkcx/2/

Also, this is the code that I'm talking about:

 document.addEventListener("scroll", function(event) { if(window.pageYOffset >= 1200){ console.log("1200"); // this is where you want your element to become absolute // positioned to his parent container // write your css changes here and apply them to elements // add relative to container and absolute with bottom 0 to element } if (window.pageYOffset <= 1200){ console.log("<1200"); } }); 
Sign up to request clarification or add additional context in comments.

Comments

1

If you want a CSS solution, here is a trick that you can do using z-index. Other than this there is a JS solution.

.wrapper { width:100% } .container { width:300px; margin:0 auto; height:1200px; background:#ccc; position: relative; z-index: -1; } .container2{ width:300px; margin:0 auto; height:1200px; background:#fcf; z-index: 1; } .element { background:#f2f2f2; position:fixed; width:50px; height:70px; margin-left:250px; border:0px solid #d6d6d6; }
<div class="wrapper"> <div class="container"> container1 <div class="element"> fixed </div> </div> <div class="container2"> container2 </div> </div>

5 Comments

Yes, I didn't use any js for this solution.
Can you add JS solution as well.
Why you need a JS solution If this is done with CSS? In JS you have to track the scroll, width of the first div and then you will able to get the solution.
because container2 overrides fixed container, I want fixed should be scroll upwards after container2 comes, check here how product image is fixed than scrolls up.
@saurabh try this jsfiddle.net/aavrug/h7rspta0/2. Subtracted 70 in offset because the element class heigth is 70px;
0

You're looking for a sticky header. There is currently no way to make a header sticky at an arbitrary scroll position using pure CSS - you'll have to look into a JavaScript solution to accomplish that.

1 Comment

Thanks for your response, I have update the question: if pure CSS solution is not possible, I will have to use JS or Jquery solution.
0

Yes, it is 100% possible to do this without any JavaScript

I updated your fiddle

Markup should be like this

<div class="wrapper"> <div class="outer-scroller"> <div class="scroll-container"> container1 <div class="fixed-header"> fixed </div> </div> </div> <div class="last-container"> container2 </div> </div> 

and css

.wrapper { width: 100%; height: 300px; } .outer-scroller { height: 140px; overflow-y: scroll; } .scroll-container { padding-top: 70px; width: 300px; height: 1200px; background: #CCC; } .last-container { width: 300px; height: 600px; background: #FCF; } .fixed-header { background: #F2F2F2; position: absolute; width: 300px; height: 70px; top: 0; pointer-events: none; } 

You'll see I've added an outer-scroller div.

The next bit is changing your CSS slightly

The new outer-scroller div is double the height of your fixed-header (for the purposes of this example) and it has an overflow-y: scroll on it.

The container inside there is still the same.

The next change is turning your position: fixed into a position: absolute and then adding padding to the top part of the div you want to scroll in order to push its content "below" the new "fixed" header.

Scrolling over the outer-scroller div then makes its content scroll, and because its height is set with an absolute element on top it then scrolls "under" the fixed header.

Once the bottom of its child content scroll-container is reached, the whole page then continues scrolling, and you get the illusion of the header disappearing.

The last bit is pointer-events: none on the header so that it doesn't scroll away when the cursor is over it (but the div below does)

2 Comments

But this has created two scrolls, one inside outer-scroller and one at window level, which is not desirable for me.
that's how the trick works, you can get rid of the scrollbars using other methods (like negative margins etc) but for what you described (or, rather, how I read it) in raw css that's the best I can give you right now

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.