Skip to content
This repository has been archived by the owner on Oct 1, 2022. It is now read-only.

Commit

Permalink
fix(modal): fix scrollbar compensation in some scaling situations
Browse files Browse the repository at this point in the history
Now the actual width of the scrollbar is used to detect if it is present or not, instead of using the wrong hypothesis that if body's rect's width is smaller than viewport's width then there is a scrollbar. Now the difference in width is compared to the width of the scrollbar.

Closes ng-bootstrap#3448
  • Loading branch information
ymeine committed Dec 2, 2019
1 parent c8c6be9 commit 3062bb1
Showing 1 changed file with 16 additions and 10 deletions.
26 changes: 16 additions & 10 deletions src/util/scrollbar.ts
Expand Up @@ -22,35 +22,41 @@ export class ScrollBar {
constructor(@Inject(DOCUMENT) private _document: any) {}

/**
* Detects if a scrollbar is present and if yes, already compensates for its
* removal by adding an equivalent padding on the right of the body.
* To be called right before a potential vertical scrollbar would be removed:
*
* - if there was a scrollbar, adds some compensation padding to the body
* to keep the same layout as when the scrollbar is there
* - if there was none, there is nothing to do
*
* @return a callback used to revert the compensation (noop if there was none,
* otherwise a function removing the padding)
*/
compensate(): CompensationReverter { return !this._isPresent() ? noop : this._adjustBody(this._getWidth()); }
compensate(): CompensationReverter {
const width = this._getWidth();
return !this._isPresent(width) ? noop : this._adjustBody(width);
}

/**
* Adds a padding of the given width on the right of the body.
*
* @return a callback used to revert the padding to its previous value
*/
private _adjustBody(width: number): CompensationReverter {
private _adjustBody(scrollbarWidth: number): CompensationReverter {
const body = this._document.body;
const userSetPadding = body.style.paddingRight;
const paddingAmount = parseFloat(window.getComputedStyle(body)['padding-right']);
body.style['padding-right'] = `${paddingAmount + width}px`;
return () => body.style['padding-right'] = userSetPadding;
const userSetPaddingStyle = body.style.paddingRight;
const actualPadding = parseFloat(window.getComputedStyle(body)['padding-right']);
body.style['padding-right'] = `${actualPadding + scrollbarWidth}px`;
return () => body.style['padding-right'] = userSetPaddingStyle;
}

/**
* Tells whether a scrollbar is currently present on the body.
*
* @return true if scrollbar is present, false otherwise
*/
private _isPresent(): boolean {
private _isPresent(scrollbarWidth: number): boolean {
const rect = this._document.body.getBoundingClientRect();
return rect.left + rect.right < window.innerWidth;
return window.innerWidth - (rect.left + rect.right) >= scrollbarWidth;
}

/**
Expand Down

0 comments on commit 3062bb1

Please sign in to comment.