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 code – jquery.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.
This is a great fix – thanks very much
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?
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!
It works in mine. I think this alone is really great. You just need to configure it well.
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?
@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.
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.
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..
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;
}
Try adding !important to the css attribute:
position: fixed !important;
great post .its really useful for me .keep it up