Перемещение позиции при переключении нескольких элементов переполнения-y

У меня проблема, которую я не знаю, как решить, надеюсь, кто-то здесь может пролить свет на нее.

У меня очень простой макет (JSBin) с горизонтально центрированным заголовком, некоторый контент для вертикальной прокрутки, липкий нижний колонтитул и меню навигации вне холста. Я хочу, чтобы пользователь не прокручивал страницу при открытии боковой панели, я делаю это, переключая класс в теге <html>:

$('button').click(function () {
    $('html').toggleClass('sidebar');
});

Класс .sidebar переместит боковую панель в режим просмотра и отключит прокрутку содержимого:

html {
  overflow-y: scroll; /* default state, always shows scrollbar */
}

html.sidebar {
  overflow-y: hidden; /* hides scrollbar when .sidebar is on canvas */
}

html.sidebar aside {
  -webkit-transform: translate3d(-100%, 0, 0); /* places .sidebar on canvas */
}

Проблема заключается в том, что он перемещает каждый элемент на странице по любой ширине полосы прокрутки <html>.

Есть ли способ предотвратить этот сдвиг в позиции (желательно, не прибегая к Javascript)?

Здесь JSBin editor, если вам нужно заглянуть в код.

Обновление. Похоже, что Javascript не является опцией, вычисление ширины прокрутки не является надежным вообще.

Ответ 1

Вы можете переключить margin-right в .container, чтобы компенсировать изменение ширины

$(function () {      
  $('button').click(function () {
    var marginR = $(".container").css("margin-right") == sWidth+"px" ? "auto" : sWidth;
    $(".container").css("margin-right", marginR);
    $('html').toggleClass('sidebar');
  });

});

function getScrollbarWidth() {
    var outer = document.createElement("div");
    outer.style.visibility = "hidden";
    outer.style.width = "100px";
    outer.style.msOverflowStyle = "scrollbar"; // needed for WinJS apps

    document.body.appendChild(outer);

    var widthNoScroll = outer.offsetWidth;
    // force scrollbars
    outer.style.overflow = "scroll";

    // add innerdiv
    var inner = document.createElement("div");
    inner.style.width = "100%";
    outer.appendChild(inner);        

    var widthWithScroll = inner.offsetWidth;

    // remove divs
    outer.parentNode.removeChild(outer);

    return widthNoScroll - widthWithScroll;
}
var sWidth = getScrollbarWidth();

Демо

Расчет ширины полосы прокрутки, взятый из этого ответа

Ответ 2

Я не могу найти решение CSS, которое работает надежно. Тем не менее, у меня есть успех со следующим Javascript:

window.onload=function(){
    document.body.style.paddingLeft = (window.innerWidth - document.body.clientWidth);
    document.body.onclick=function(){
            document.body.style.paddingLeft = (window.innerWidth - document.body.clientWidth);
    }
}

Я еще не проанализировал, на что влияет обработка на запуск этого кода каждый раз, когда кто-то нажимает на мой сайт (это, вероятно, уродливо), но он работает.