12

I'm using the Snap.js plugin - (it allows you to create scrolling side drawers/panels).

It works by creating 3 absolutely positioned divs, one of which contains main content.

Is there a way to position a div fixed to the top of the window when it is itself inside the absolutely positioned div.

At the moment i'm just getting the fixed div to pin to the top of the absolutely positioned div, rather than to the top of the browser. When I scroll, the div remains fixed to the top of the main content, but not the window.

For example:

<div style="position:absolute;">

    <div style="position:fixed;top:0">
       <!-- some content which needs to be pinned to top of window -->
    </div>

</div>

At the moment i'm using javascript to track the scroll offset and manually adjust the top position of the child div, which is not ideal for performance.

Any help appreciated!

Pavlo
  • 43,301
  • 14
  • 77
  • 113
Ray A
  • 307
  • 2
  • 14
  • 1
    the absolutely positioned div has the following css applied: translate3d(0px, 0px, 0px), if I remove it a fixed element behaves as it should and is pinned to the top of the window. Any ideas on why this is? – Ray A Jun 10 '13 at 00:06
  • That's what your example code does. (Is that what you intended?) When you set position fixed on an element it takes it out of the flow of the document and makes it relative to the viewport. Are you saying snap.js breaks this? – BjornJohnson Jun 10 '13 at 00:15
  • Interesting. Does this help? http://code.google.com/p/chromium/issues/detail?id=20574 – BjornJohnson Jun 10 '13 at 00:19
  • I'm using firefox 21.0 mainly and it has the problem as described. Do you have any ideas on a workaround this - or am I going to have to make amendments to the way snap.js works? Their is a bit of info here too https://github.com/jakiestfu/Snap.js/issues/24 – Ray A Jun 10 '13 at 00:51
  • if you go here http://jakiestfu.github.io/Snap.js/demo/apps/default.html and add the following to div with the id content, the problem can be recreated.
    – Ray A Jun 10 '13 at 00:56
  • See my comment regarding CSS3 transform and fixed positioned child elements. – Marc Audet Jun 10 '13 at 12:03

2 Answers2

2

I've made a fiddle showing my javascript workaround - it jitters when scrolling in internet explorer, any ideas.

<div id="displayed-content" class="snap-content scrollable">
    <div><!-- regular content --></div>
        <div><!-- fixed content --></div>
    <div><!-- footer content --></div>
</div>

http://jsfiddle.net/bxRVT/

Ray A
  • 307
  • 2
  • 14
  • You did quite a bit of work here. Hard to say how best to improve IE performance. You are really on the cutting edge of CSS3 technologies. My first guess is that the transforms don't play well with jQuery .scrollTop, but it would be a whole project in itself to try to improve upon what you have done. I will give you a vote for effort! – Marc Audet Jun 10 '13 at 12:57
  • Thanks, i'm using the above implementation for now until I figure something better out. – Ray A Jun 10 '13 at 15:05
0

I am guessing a bit about what you are trying to do, but you might be looking for something like this:

<div class="local-wrap">
    <div class="fixed">
       Some content which needs to be pinned to top of window
    </div>
    <div class="port">
        Regular content...
    </div>
</div>

and apply the following CSS:

.local-wrap {
    position: relative;
}
.local-wrap .fixed {
    position: absolute;
    top: 0;
    left: 0;
    background-color: lightgray;
    width: 100%;
    height: 5.00em;
}
.local-wrap .port {
    position: relative;
    top: 5.00em;
    min-height: 10em;
    height: 15em;
    overflow: auto;
    border: 1px solid gray;
    border-width: 0 1px 1px 1px;
}

Demo fiddle: http://jsfiddle.net/audetwebdesign/pTJbW/

Essentially, to get a fixed block with respect to a block element, you need to use absolute positioning. Fixed positioning is always with respect to the root element or view port, so position: fixed won't help you.

What I have done is define a .local-wrap container, with two child blocks, one which is positioned absolutely to the top of .local-wrap and the other in regular flow. I used position: relative to position it below .fixed, but a top margin would have also worked.

I fixed some heights to demonstrate scrolling content within the local window/port, but that can be changed depending on your design and application.

Disclaimer

I am not familiar with snap.js so there may be other considerations to consider.

Comment on CSS3 Transform and Fixed Elements

According to the CSS3 specs, if you apply a transform to an element, call it div.transformed, then div.transformed creates a new stacking context and serves as a containing block for any fixed position child elements that it contains, which is why in your scenario, the fixed position context does not stay at top of the window.

For reference, see Mozilla Developer Network -> CSS Reference -> Transform

Marc Audet
  • 46,011
  • 11
  • 63
  • 83
  • Unfortunately that doesn't work as the div needs to be pinned to the top of the window, but would scroll with the window as the .local-wrap in your example scrolls. The normal method of using a fixed position div does work but only if the css tranform is removed from the parent absolutely positioned div. Is there a workaround for this? At the moment i'm using javascript to adjust the top css property for the floating div everytime the window is scrolled - this works ok on some browsers but is choppy on others. – Ray A Jun 10 '13 at 11:16
  • 1
    I've created a jsfiddle to illustrate this better http://jsfiddle.net/pTJbW/10/ . Make your browser window smaller until scrollbars appear in the output, when you scroll the fixed header will scroll with the content. However, if your remove the css transform in the css on the content and update, you will notice when you scroll the header remains fixed. – Ray A Jun 10 '13 at 11:26
  • Good fiddle, the picture is much clearer now. If I understand things, if you remove the CSS transform property, then snap.js will not work, and this is the problem that you are trying to get around. – Marc Audet Jun 10 '13 at 11:30
  • Thanks for sticking with me! Yes, that is exactly the issue i'm facing. I've made another fiddle, this time showing my JS workaround - have a look at the JS code - it jitters in mobile safari and internet explorer 8 - any ideas? – Ray A Jun 10 '13 at 12:44