Layout shift
Opening/closing Fancybox may cause layout shift. Here you will learn the reasons why this happens and what the solutions are.
The Cause
Compare the two images below.
Note that the second screenshot shows a vertical scrollbar and the content is not directly in the middle of the screen. Now imagine the content being higher than the screen. What would happen? There would probably be two vertical scroll bars.
If you're happy with the vertical scrollbar being visible and you're not worried about the possibility of two vertical scrollbars appearing (if you use Fancybox only to display images, for example), just set the option hideScrollbar:false
and forget about the layout shfting problem.
Now, as you can see, hiding the vertical scrollbar not only makes the modal visually better, but also avoids the problem of two vertical scrollbars.
So, how does Fancybox hide the scrollbar? Using CSS, just like any modal script, something like this:
body {
overflow: hidden;
}
And this is where the problem arises. Since the vertical scrollbar used to take up space, but is now gone, the width of the window changes and that affects the layout.
So, if your body
and fixed or absolutely positioned elements had width 100%
and it was, for example, 1536px
, their width will now be 1536px + "vertical scrollbar width"
.
To address the problem with the body
element, Fancybox calculates the width of the vertical scrollbar and compensates for its disappearance by giving the body
element an additional margin-right
value. It works, but unfortunately it doesn't solve the problem with fixed or absolutely positioned elements, but there are solutions.
Solutions
Do Not Hide Scrollbars
This is the easiest solution - just don't hide the scrollbars.
Fancybox.bind("[data-fancybox]", {
hideScrollbar: false,
});
Use CSS variable
Fancybox calculates the width of the vertical scrollbar before hiding it and stores it in the --fancybox-scrollbar-compensate
CSS variable. Use this to compensate for the scrollbar disappearing. The way of use depends on your needs, you can increase the padding, margin or change element width. Example:
#navbar {
margin-right: var(--fancybox-scrollbar-compensate, 0px);
}
Use Additional Container
Another great solution is to use an additional wrapper element, give it a height of 100vh
and make it scrollable.
#root {
height: 100vh;
overflow: auto;
}