Short Answer
If you do not want to display the scrollbar all the time, wrap your content into <div>
elements etc. you can use JavaScript to add a certain value to all media queries when the scrollbar is shown.
// check whether scrollbar is visible
var isScrollbarVisible = window.innerWidth > document.documentElement.clientWidth;
// search for media rule
var mediaRule = document.styleSheets[i].cssRules[j];
// update media rule
mediaRule.media.mediaText = '..'
Long Answer
I wrote a small script which you can include on your page. It detects when the window is resized and changes all media queries if needed. The value of the css variable --replace-media-scrollbar
is used as the width of the scrollbar or 15px
if no value was found. This works for the media queries with
, min-width
, max-width
, height
, min-height
and max-height
even when they are connected using and
.
JavaScript:
function* visitCssRule(cssRule) {
// visit imported stylesheet
if (cssRule.type == cssRule.IMPORT_RULE)
yield* visitStyleSheet(cssRule.styleSheet);
// yield media rule
if (cssRule.type == cssRule.MEDIA_RULE)
yield cssRule;
}
function* visitStyleSheet(styleSheet) {
try {
// visit every rule in the stylesheet
var cssRules = styleSheet.cssRules;
for (var i = 0, cssRule; cssRule = cssRules[i]; i++)
yield* visitCssRule(cssRule);
} catch (ignored) {}
}
function* findAllMediaRules() {
// visit all stylesheets
var styleSheets = document.styleSheets;
for (var i = 0, styleSheet; styleSheet = styleSheets[i]; i++)
yield* visitStyleSheet(styleSheet);
}
// collect all media rules
const mediaRules = Array.from(findAllMediaRules());
// read scrollbar width
var style = getComputedStyle(document.documentElement);
var scrollbar = style.getPropertyValue('--replace-media-scrollbar') || '15px';
// update media rules
if (scrollbar != '0px') {
var oldValue = '0px';
function updateMediaRulesScrollbar() {
var newValue = window.innerWidth > document.documentElement.clientWidth ? scrollbar : '0px';
// if value changed
if (oldValue != newValue) {
for (var i = 0, mediaRule; mediaRule = mediaRules[i]; i++) {
var regex = RegExp('\\((width|min-width|max-width|height|min-height|max-height): (calc\\([^)]*\\)|[^)]*)\\)', 'g');
var replacement = '($1: calc($2 - ' + oldValue + ' + ' + newValue + '))';
mediaRule.media.mediaText = mediaRule.media.mediaText.replace(regex, replacement);
console.log(mediaRule);
}
}
oldValue = newValue;
}
updateMediaRulesScrollbar();
window.onresize = updateMediaRulesScrollbar;
}
Optional CSS:
:root {
--replace-media-scrollbar: 15px;
}
@media all and (max-width: calc(980px + scrollbar-width))
– Ardrey