JSFiddle - React, Tailwind, and code Playground
HTML
<!--
-- Step 1:
--
-- Initially this lays out correctly. The inner grid's track is 200px
-- wide and Chrome adds the scrollbar to that in order to size the
-- track on the parent.
-->
<div style="display: grid; grid: max-content / max-content; place-content: center center; height: 100%;">
<div style="display: flex; flex-flow: column nowrap; height: 200px;">
<h1>wait 5s</h1>
<div style="display: grid; grid-template-columns: minmax(0, 200px); overflow: auto;">
<span>123</span>
<span>abc</span>
<span>123</span>
<span>abc</span>
<span>123</span>
<span>abc</span>
<span>123</span>
<span>abc</span>
<span>123</span>
<span>abc</span>
</div>
</div>
</div>
CSS
html, body {
height: 100%;
}
body {
margin: 0;
}
JavaScript
const grid1 = document.querySelector("div");
const grid2 = grid1.querySelector("div");
/*
* Step 2: the bug:
*
* But when causing a big layout to be done with JS, it seems like
* the outer track is sized _without_ the scrollbar (200px instead
* of 215px, assuming the scrollbar is 15px wide) and the inner grid
* _shrinks_ to fit (so the inner grid's track is 185px)
*/
setTimeout(() => {
grid2.style.display = "none";
grid1.clientWidth;
grid2.style.display = "grid";
}, 5e3);
/*
* The workaround:
*
* Nearly any style operation will cause the layout to be correct
* (Step 0) again, I found adding/removing a child element to the
* inner grid to be the most reliable (there seeemed to be some
* situations where )
*/
setTimeout(() => {
const s = document.createElement("span");
grid2.append(s);
grid1.clientWidth;
s.remove();
}, 10e3);