PhotoSwipe
PhotoSwipe copied to clipboard
Hiding the scrollbar
I found the vertical scrollbar to be distracting (and confusing) when viewing images. I'm sure there is a cleaner solution, but here is what I did to allow photoswipe to display on top of the scroll bars (effectively hiding them when viewing images). Photoswipe looks much better now!
Test page: http://www.nwhikers.net/test.htm (be sure to hit refresh)
Original code (decided to ditch this):
<body><div id="body_scroll"><div id="body_padding">
<script type="text/javascript">
var isFixedPosition = function() {
// would be best to use _isFixedPosition from photoswipe rather than re-create it here
}
if (isFixedPosition()) { // only do this if photoswipe will use position: fixed
document.body.setAttribute("style", "overflow: hidden; margin: 0px");
document.getElementById("body_scroll").setAttribute("style", "position: absolute; width: 100%; height: 100%; overflow: auto");
document.getElementById("body_padding").style.padding = "8px"; // or set class
}
</script>
<!-- body content goes here -->
</div></div></body>
EDIT: revised code (based on comments below):
// add this in var _options = {
_options.hideScroll: true,
// after this line in init: function() {
var oldPhone = _features.isOldIOSPhone || _features.isOldAndroid || _features.isMobileOpera;
// add these lines:
_features.hideScroll = (_options.hideScroll && !oldPhone && _options.modal && document.body.clientWidth);
if (_features.hideScroll) {
_features.restoreScroll = document.body.getAttribute('style');
document.body.style.width = window.getComputedStyle(document.body).width;
document.body.style.overflow = 'hidden';
}
// add these lines:
if (_features.hideScroll) {
if (_features.restoreScroll) {
document.body.setAttribute('style', _features.restoreScroll);
} else {
document.body.removeAttribute('style');
}
}
// before this line in close: function() {
_showOrHide(self.currItem, null, true, self.destroy);
I'm aware of this issue and PhotoSwipe does not hide scrollbar on purpose.
Your technique is fine (even though it can potentially causes issues in older browsers that don't support overflow-y:scroll
well), Google Photos uses a similar one, but I can not ship it "by default".
PhotoSwipe could remove scrollbar just by applying overflow:hidden
& padding-right
to html/body itself directly before it is opened. But it causes very complex relayout and paint (as a browser has to recalculate layout of the whole page), which will cause lag during the opening transition (especially if there is a lot of content on page).
would be best to use _isFixedPosition from photoswipe rather than re-create it
I'm planning to drop non-fixed position in the new version. If browser won't support it - new version will just open image in new tab.
Thanks, just curious what issues this technique would cause in older browsers? Best case, wouldn't they just show the scrollbar? Worst case 2 scrollbars? Seems a small price to pay to get rid of the scrollbar for the vast majority of users.
I avoided padding-right for a couple reasons. First, as you said it causes relayout (whereas my solution does not). Also, I believe you need to guess at the scrollbar width.
Worst case - page won't scroll at all or won't have momentum scrolling. check https://github.com/filamentgroup/Overthrow#browser-support
Browser does a lot of things to optimize the performance of the main scroll, and even though scroll on inner element looks alike, it might behave slower or just differently. For example, if you load your page and try to scroll down with keyboard arrow keys - it won't work unless the overflow:scroll element is focused.
Thanks for the feedback. I hadn't considered these side effects. I ended up ditching my original technique in favor or your first suggestion. I'm assuming that setting the body width before removing the scrollbar will minimize relayout.
I updated the code above to use getComputedStyle since it returns the decimal width. I was originally using clientWidth which had undesirable side effects due to it being a rounded width.