6

I have an absolutely positioned panel (fixed height, overflow scroll) and a grid with square tiles (10 columns). In Chrome, the grid renders correctly:

enter image description here

But in FF/Safari, the last column is displayed behind wrapper's scrollbar which is odd:

enter image description here

enter image description here

What I want is the same behavior in all browsers (like in Chrome). How do I get this?

jsFiddle

:root {
 --ck-character-grid-tile-size: 24px;
}

body * {
  box-sizing: border-box;
}

.wrapper { 
  height: 100px;
  overflow-y: auto;
  overflow-x: hidden;
  background: red;
  position: absolute;
  top: 50px;
  left: 50px;
  outline: 1px solid black;
}

.grid {
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  background: blue;
}

button {
  background: yellow;
  width: var(--ck-character-grid-tile-size);
  height: var(--ck-character-grid-tile-size);
  min-width: var(--ck-character-grid-tile-size);
  min-height: var(--ck-character-grid-tile-size);
  border: 0;
  padding: 0;
  overflow: hidden;
  outline: 1px solid black;
}
<div class="wrapper">
  <div class="grid">
    <button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button><button>x</button>
  </div>  
</div>
oleq
  • 15,697
  • 1
  • 38
  • 65
  • you can add padding-right on the parent or margin-right on the child to stay from the scrollbar area : https://jsfiddle.net/61mnjezw/ – G-Cyrillus Nov 26 '19 at 16:15
  • 3
    I get the same results in Chrome as I do in Firefox for your fiddle. – TylerH Nov 26 '19 at 16:15
  • On my Chrome (78.0.3904.108) I get the incorrect result (the same as in Firefox and Safari). Maybe it's OS specific (how scrollbars behave)? – Reinmar Nov 26 '19 at 16:19
  • the snippet goes wrong for my latest Firefox under windows, fine with chrome – G-Cyrillus Nov 26 '19 at 16:20
  • @TylerH Forgot to mention, I'm running things on MacOS. It could make a difference. – oleq Nov 26 '19 at 16:20
  • safari was the key word here about MacOs :) but my win FF goes wrong too. – G-Cyrillus Nov 26 '19 at 16:21
  • 2
    OK, I took another look. The Fiddle in Chrome hides the grid behind the scrollbar when I first load the page, but then when I click "run" (without changing anything), it repaints with the grid expanded so that the scrollbar isn't covering it up. Very weird. – TylerH Nov 26 '19 at 16:22
  • and padding/margin doesn't solve anything here ? this behavior is since ever , it is not only about a grid child . might be a few dupes that will be good enough – G-Cyrillus Nov 26 '19 at 16:31
  • since this a known bug and can be solved in many other ways, in your case since you know how many items there will be you can define a width to the grid `width: calc(var(--ck-character-grid-tile-size) * 10);` maybe tweak it to account for borders – Rainbow Nov 26 '19 at 16:46
  • @TylerH yes this is common in Chrome where the repaint fixes some issue or to be more accurate trigger some extra calculation. You can do this with an animation for example and it will also work without the need of running the snippet again: https://jsfiddle.net/73tcpwky/ .. Some related question where I used that hack: https://stackoverflow.com/q/58350222/8620333 / https://stackoverflow.com/q/58289173/8620333 – Temani Afif Nov 26 '19 at 20:38

2 Answers2

2

According to CSS Tricks article, Preventing a Grid Blowout, the issue is connected with the sizing of the grid:

The real fix isn't all that difficult — we only need to understand what is happening. I can't promise I'm explaining this 100% accurately, but the way I understand it, the minimum width of a grid column is auto. […]

To apply our fix, we need to make sure that there is the column has a definite minimum width instead of auto.

The fix proposed in article, minmax, seems to be working also for the case in question:

grid-template-columns: repeat( 10, minmax( 0, var(--ck-character-grid-tile-size) ) );

The simpler version, using fr unit, also seems to work:

grid-template-columns: repeat( 10, minmax( 0, 1fr ) );

Demo of the fix: https://jsfiddle.net/gp8r0f94/

Comandeer
  • 156
  • 1
  • 11
-3

That's just how things are, but you can use JS to calculate the width of the scrollbar and add that as a padding. You can use this answer:

Prevent scroll-bar from adding-up to the Width of page on Chrome

I replaced margin with padding:

var checkScrollBars = function(){
    var b = $('body');
    var normalw = 0;
    var scrollw = 0;
    if(b.prop('scrollHeight')>b.height()){
        normalw = window.innerWidth;
        scrollw = normalw - b.width();
        $('#container').css({paddingRight:'-'+scrollw+'px'});
    }
}
JMRC
  • 1,473
  • 1
  • 17
  • 36
  • If you think the question has already been answered, please flag the question as a duplicate rather than posting an answer that only links to an existing answer elsewhere on the site. – TylerH Nov 26 '19 at 16:41
  • It's a different question which happens to solvable with the same answer of another question. Maybe someone will offer a different solution and closing down the answer takes that opportunity away. – JMRC Nov 26 '19 at 16:53
  • 1
    In that case, you should provide a gist of the answer here, as link-only answers are still of little value. What if the answer (or its question) you link to gets deleted? What if it gets changed? Etc. – TylerH Nov 26 '19 at 16:56