Делаю следующий образом.
html {
&.overflow {
overflow: hidden;
margin-right: var(--scrollbar-width, 0);
}
}
При отсутствии скроллбара добавляется отступ
--scrollbar-width, равный его ширине, которая определяется скриптом:
const getScrollbarWidth = function () {
const $scrollDiv = document.createElement('div');
$scrollDiv.style.cssText = 'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;';
document.body.appendChild($scrollDiv);
const scrollBarWidth = $scrollDiv.offsetWidth - $scrollDiv.clientWidth;
document.body.removeChild($scrollDiv);
return scrollBarWidth;
};
В момент открытия и закрытия попапа запускается скрипт:
const $html = $('html');
if ($html.is('.overflow')) {
$html.removeClass('overflow');
$html.css('--scrollbar-width', '');
} else {
$html.addClass('overflow');
$html.css('--scrollbar-width', `${getScrollbarWidth()}px`);
}
А скролл попапа делать уже внутри блока с попапом.