It might sound like this has been asked a million times before, but I have not found anything that really solves all of the problems I am trying to solve. With this disclaimer out of the way, here is what I am trying to achieve:
- A sidebar, fixed to the right
- A content area, that might be scrollable
- The scrollbar of the content area needs to be to the right of the sidebar
- It should be possible to display an overlay
- The overlay should be scrollable as well
- While the overlay is visible, the underlying content area should not be scrollable
- Showing the overlay with its scrollbar should not result in a re-layout of the underlying content area, e.g. because of overflow: hidden
The combination of all these requirements breaks each solution that I have tried.
I have two solutions now, that are close but still not good enough:
Solution 1 doesn't solve requirement 7.
Solution 2 has two scrollbars when the overlay is visible.
Solution 1:
function showOverlay() {
  var style = document.body.style;
  style.overflow = 'hidden';
  document.getElementById('overlay').style.display = 'block';
}
function closeOverlay() {
  var style = document.body.style;
  style['overflow-y'] = 'scroll';
  document.getElementById('overlay').style.display = 'none';
}* {
  margin: 0;
  box-sizing: border-box
}
html {
}
body {
  position: relative;
  width: 100%;
  overflow-y: scroll;
}
.content {
  position: relative;
  display: block;
  background-color: lightblue;
  border: 2px solid white;
  width: calc(100% - 60px)
}
.fixed {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 1000;
  background-color: lightgreen;
  width: 60px;
  border: 2px solid black;
  text-align: right;
}
#overlay {
  display: none;
  position: fixed;
  z-index: 10000;
  left: 0;
  top: 0;
  bottom: 0;
  right: 0;
  background-color: rgba(32,32,32,0.5);
  overflow-y: scroll;
}
.overlay-content {
  margin: 50px auto;
  height: 1000px;
  width: 80%;
  background-color: yellow;
}<div class="content">
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    <button onclick="showOverlay()">show overlay</button>
  </div>
<div class="fixed">A<br/>B<br/>C</div>
<div id="overlay">
  <div class="overlay-content">
    <button onclick="closeOverlay()">Close overlay</button>
  </div>
</div>Solution 2:
function showOverlay() {
  var style = document.body.style;
  style.top = '-' + document.documentElement.scrollTop + 'px';
  style.position = 'fixed';
  document.getElementById('overlay').style.display = 'block';
}
function closeOverlay() {
  var style = document.body.style;
  style.position = 'relative';
  style.top = 0;
  document.getElementById('overlay').style.display = 'none';
}* {
  margin: 0;
  box-sizing: border-box
}
html {
}
body {
  position: relative;
  width: 100%;
  overflow-y: scroll;
}
.content {
  position: relative;
  display: block;
  background-color: lightblue;
  border: 2px solid white;
  width: calc(100% - 60px)
}
.fixed {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 1000;
  background-color: lightgreen;
  width: 60px;
  border: 2px solid black;
  text-align: right;
}
#overlay {
  display: none;
  position: fixed;
  z-index: 10000;
  left: 0;
  top: 0;
  bottom: 0;
  right: 0;
  background-color: rgba(32,32,32,0.5);
  overflow-y: scroll;
}
.overlay-content {
  margin: 50px auto;
  height: 1000px;
  width: 80%;
  background-color: yellow;
}<div class="content">
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    Body<br/>
    <button onclick="showOverlay()">show overlay</button>
  </div>
<div class="fixed">A<br/>B<br/>C</div>
<div id="overlay">
  <div class="overlay-content">
    <button onclick="closeOverlay()">Close overlay</button>
  </div>
</div>I think that solution 1 is the better one of the two, but is it possible to prevent that relayout from happening?
Please note, that I am trying to find a solution that works without using Javascript to detect the scrollbar width.
 
    