javascriptcssfirefox

Scrollbar covers content of inline element with overflow auto in Firefox


I'm looking for a simple (CSS-) solution for the following problem:

I filled an outer DIV with 8 lines of nested DIVs. The outer DIV is displayed as inline-block with overflow-y auto and hidden overflow-x. The width of the outer DIV should not be specified firmly. Firefox on Windows covers scrollable content of the widest line(s) with a scrollbar. I have tried many (see below) different browsers, but Firefox was the only candidate with this behavior.

.outer {
  display: inline-block;
  border: 1px solid #000;
  height: 6lh;
  overflow-x: hidden;
  overflow-y: auto;
}

.inner {
  padding: 2px 5px;
  text-wrap: nowrap;
}
<div id="outer" class="outer">
    <div id="inner" class='inner'>short</div>
    <div class='inner'>longer</div>
    <div class='inner'>another</div>
    <div class='inner'>medium</div>
    <div class='inner'>overflow</div>
    <div class='inner'>inline</div>
    <div class='inner'>scrollbar</div>
    <div class='inner'>incomprehensibility</div>
</div>

Screenshot of Firefox hiding content behind scrollbar

Firefox: reported dimensions of DIVs

DIV dimension visible auto scroll hidden
outer offsetWidth 148 148 165 148
clientWidth 129 129 146 146
inner offsetWidth 129 129 146 146
clientWidth 129 129 146 146

Other browsers: reported dimensions of DIVs (outer offsetWidth slightly differs, depending on browser's scrollbar width)

DIV dimension visible auto scroll hidden
outer offsetWidth 163 163 163 148
clientWidth 146 146 146 146
inner offsetWidth 146 146 146 146
clientWidth 146 146 146 146

A look on a shorter content that doesn't force scrolling results in the same values as shown in the upper second table. There's no difference between Firefox an the others.

.outer {
  display: inline-block;
  border: 1px solid #000;
  height: 6lh;
  overflow-x: hidden;
  overflow-y: auto;
}

.inner {
  padding: 2px 5px;
  text-wrap: nowrap;
}
<div id="outer" class="outer">
    <div id="inner" class='inner'>short</div>
    <div class='inner'>incomprehensibility</div>
</div>

Neither playing around with CSS attributes (grid, flex, transform...) nor searching for conclusions was successful. My only solution yet is to manipulate the dimensions via Javascript. The clientWidth of the outer DIV is always the same in any browser except Firefox, independent of the chosen overflow method or the content's height.

My solution with Javascript:

function correctFF() {
    let o = document.getElementById('outer');
    let i = document.getElementById('inner');

    // get dimensions of overflow-y: scroll
    o.style.overflowY = 'scroll';
    let ocs = o.clientWidth;
    let oos = o.offsetWidth;

    // get dimensions of overflow-y: auto
    o.style.overflowY = 'auto';
    let oca = o.clientWidth;

    // Firefox (clientWidth of overflow auto < scroll)?
    // => enlarge outer DIV to offsetWidth of overflow scroll
    if(oca < ocs) o.style.width = oos + 'px';
}

Do you have any ideas?

Tested browsers (desktop)

Tested browsers (mobile)


Solution

  • Try setting scrollbar gutter on .outer to reserve space for the scrollbar:

    scrollbar-gutter: stable;
    

    .outer {
      display: inline-block;
      border: 1px solid #000;
      height: 6lh;
      overflow-x: hidden;
      overflow-y: auto;
      scrollbar-gutter: stable;
    }
    
    .inner {
      padding: 2px 5px;
      text-wrap: nowrap;
    }
    <div id="outer" class="outer">
        <div id="inner" class='inner'>short</div>
        <div class='inner'>longer</div>
        <div class='inner'>another</div>
        <div class='inner'>medium</div>
        <div class='inner'>overflow</div>
        <div class='inner'>inline</div>
        <div class='inner'>scrollbar</div>
        <div class='inner'>incomprehensibility</div>
    </div>