How to get Fancybox 1.3.1 to stay put!

I recently had a need to use a Fixed position overlay and found that Fancybox breaks if I set #fancybox-wrap to position:fixed. I believe the centerOnScroll option was supposed to solve this problem by recalculating the absolute position of #fancybox-wrap upon scrolling. The problem with this approach is that the overlay ‘shudders’ or ‘feels jumpy’ when you scroll in Firefox, Opera and IE7+.

Luckily the fix is actually pretty simple with the following steps:

1. Get a copy of the source codejquery.fancybox-1.3.1.zip

2. Do a in-code-search

Open jquery.fancybox-1.3.1.js and look for the fancybox_get_viewport function (should be around line 56), the function should look like this:

fancybox_get_viewport = function() {
  return [ $(window).width(), $(window).height(), $(document).scrollLeft(), $(document).scrollTop() ];
},

3. Change it to look like this:

fancybox_get_viewport = function() {
  var isFixed = wrap.css('position') === 'fixed'; // add support for fixed positioning
  return [ $(window).width(), $(window).height(), isFixed ? 0 : $(document).scrollLeft(), isFixed ? 0 : $(document).scrollTop() ];
},

4. Add some CSS

Add the following clauses to your CSS files (ensure these clauses load after the jquery.fancybox-1.3.1.css file):

#fancybox-wrap {
  position: fixed; 
}
* html #fancybox-wrap {	/* IE6 */
  position: absolute;
}

That’s it!

Basically what the fix does is detect whether the wrapper is a fixed position element, if so it would return 0 for the scrollLeft and scrollTop values of the viewport. So even if you’re not using a fixed position element you can add this fix in as it’s non-destructive.

  • Scott Sinclair

    This is a great fix – thanks very much :)

  • Cam

    It works… BUT when cycling through different image sizes in a set, the box does not resize smoothly and centered on screen – it 'reloads' from the bottom up. Can you fix?

    • http://www.ozzu.com/ Bigwebmaster

      I know you posted this a long time ago, but I had this same problem as I was trying to load another fancybox dialog from one that was currently already open. Everytime I did this it would fade out and then animate in from the bottom up. Was highly annoying. Took me a few hours but I figured out a solution and now it works perfectly. Basically if you want to use this "fixed" solution you also need to add a few other lines which deal with the animated parts. Here is the fix:

      Around line 378 you will find this:

      [code]start_pos = {
      top : pos.top,
      left : pos.left,
      width : wrap.width(),
      height : wrap.height()
      };[/code]

      Replace that with this:

      [code]start_pos = {
      top : ((wrap.css('position') === 'fixed') ? pos.top - $(this).scrollTop() : pos.top),
      left : pos.left,
      width : wrap.width(),
      height : wrap.height()
      };[/code]

      Around line 1164 you will see the same thing. Replace that as well with the new code. This basically changes the position top parameter sent to the _draw function if the wrap css is set to fixed. Without this change it calculates it incorrectly. Hope this helps someone!

  • http://seitan.tv Jerry Fisher

    It works in mine. I think this alone is really great. You just need to configure it well.

  • Alfred R

    Great solution for 1.3.1 but what about 1.3.4? Is there any possibility to achieve the same effect in 1.3.4?

  • caphun

    @alfred: Yep, the code in 1.3.4 has changed slightly but same principles apply… change "_get_viewport" to look like this:

    [code lang=""javascript""]

    _get_viewport = function() {

    var isFixed = wrap.css('position') === 'fixed'; // add support for fixed positioning

    return [

    $(window).width() - (currentOpts.margin * 2),

    $(window).height() - (currentOpts.margin * 2),

    (isFixed ? 0 : $(document).scrollLeft()) + currentOpts.margin,

    (isFixed ? 0 : $(document).scrollTop()) + currentOpts.margin

    ];

    },

    [/code]

    Then modify css as instructed in the article.

  • http://www.photoshopmesta.net/sic Joonas

    What kinda breaking occurs?

    I tested 1.3.4 with position fixed and it worked fine in all browsers except i didn't try ie6. Only problems i saw.. happened if i had "centerOnScroll" and #fancybox-wrap position: fixed on at the same time.

  • Owen

    It works perfectly but some transition and easing effect are not functioning. like elastic and easeOutBack.
    Is there a fix for this to work? Please help..

  • Peter

    I tried this fix on 1.3.4 and I am still getting the box centered vertically and horiz.

    on line 673 I changed to:
    _get_viewport = function() {

    var isFixed = wrap.css('position') === 'fixed'; // add support for fixed positioning

    return [

    $(window).width() - (currentOpts.margin * 2),

    $(window).height() - (currentOpts.margin * 2),

    (isFixed ? 0 : $(document).scrollLeft()) + currentOpts.margin,

    (isFixed ? 0 : $(document).scrollTop()) + currentOpts.margin

    ];

    },

    and changed my css to:

    #fancybox-wrap {
    /*position: absolute;*/
    position: fixed;
    top: 50;
    /*top: 0;*/
    left: 0;
    padding: 20px;
    z-index: 1101;
    outline: none;
    display: none;
    }
    * html #fancybox-wrap { /* IE6 */
    position: absolute;
    }

    • Guest

      Try adding !important to the css attribute:

      position: fixed !important;

  • http://www.oursoftworld.com mani

    great post .its really useful for me .keep it up