Search code examples
htmlcssflexbox

Overflow auto not working with justify-content: flex-end


I'm trying to get an element to have items aligned to the right, and all overflowing elements to be hidden but accessed by scrollbar.

But it seems like the scrollbar disappears when specifying justify-content: flex-end. Why is that, and how do I fix it?

Here is demo: https://jsfiddle.net/efguz4mp/1/

.row {
  width: 100%;
  max-width: 500px;
  background: #DADADA;
  display: flex;
  overflow: auto;
  justify-content: flex-end;
}

.box {
  width: 200px;
  height: 40px;
  margin: 4px 10px;
  background: red;
  flex-shrink: 0;
}
<div class="row">
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
</div>

...and here is demo without justify-content: flex-end;: https://jsfiddle.net/efguz4mp

.row {
  width: 100%;
  max-width: 500px;
  background: #DADADA;
  display: flex;
  overflow: auto;
}

.box {
  width: 200px;
  height: 40px;
  margin: 4px 10px;
  background: red;
  flex-shrink: 0;
}
<div class="row">
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
</div>


Solution

  • When an overflow occur to the left (or top), a scroll doesn't get rendered, and the reason is that a HTML document's normal flow is left-to-right (top-to-bottom).

    Flexbox has a row-reverse direction, which will solve that, thought 2 things comes with that:

    • One need to reorder the items or use an inner wrapper

    • I.a. Firefox and Edge doesn't show the scroll (possible bug)

    Stack snippet

    .row {
      width: 100%;
      max-width: 500px;
      background: #DADADA;
      display: flex;
      flex-direction: row-reverse;
      overflow: auto;
    }
    .box {
      width: 200px;
      height: 40px;
      margin: 4px 10px;
      background: red;
      flex-shrink: 0;
    }
    
    /* no wrapper */
    .row > .box:nth-child(1) { order: 6; }
    .row > .box:nth-child(2) { order: 5; }
    .row > .box:nth-child(3) { order: 4; }
    .row > .box:nth-child(4) { order: 3; }
    .row > .box:nth-child(5) { order: 2; }
    .row > .box:nth-child(6) { order: 1; }
    
    /* wrapper */
    .inner {
      display: flex;
    }
    <div class="row">
      <div class="box">1</div>
      <div class="box">2</div>
      <div class="box">3</div>
      <div class="box">4</div>
      <div class="box">5</div>
      <div class="box">6</div>
    </div>
    
    <div><br><br></div>
    
    <div class="row">
      <div class="inner">
        <div class="box">1</div>
        <div class="box">2</div>
        <div class="box">3</div>
        <div class="box">4</div>
        <div class="box">5</div>
        <div class="box">6</div>
      </div>
    </div>


    Possible workarounds are:

    • Use direction: rtl to change the flow direction

    .row {
      width: 100%;
      max-width: 500px;
      background: #DADADA;
      display: flex;
      overflow: auto;
      direction: rtl;
    }
    .inner {
      display: flex;
      direction: ltr;
    }
    .box {
      width: 200px;
      height: 40px;
      margin: 4px 10px;
      background: red;
      flex-shrink: 0;
    }
    <div class="row">
      <div class="inner">
        <div class="box">1</div>
        <div class="box">2</div>
        <div class="box">3</div>
        <div class="box">4</div>
        <div class="box">5</div>
        <div class="box">6</div>
      </div>
    </div>

    • Use transform to flip the row element

    .row {
      width: 100%;
      max-width: 500px;
      background: #DADADA;
      display: flex;
      overflow: auto;
      transform: scale(-1,1);        /*  flip horizontally  */
    }
    .inner {
      display: flex;
      transform: scale(-1,1);        /*  reset so items is not backwards  */
    }
    .box {
      width: 200px;
      height: 40px;
      margin: 4px 10px;
      background: red;
      flex-shrink: 0;
    }
    <div class="row">
      <div class="inner">
        <div class="box">1</div>
        <div class="box">2</div>
        <div class="box">3</div>
        <div class="box">4</div>
        <div class="box">5</div>
        <div class="box">6</div>
      </div>
    </div>

    • Use a script on page load to scroll to the right

    window.addEventListener("load", function(e) {
      var el = document.querySelector(".row");
      el.scrollLeft = el.scrollWidth;
    });
    .row {
      width: 100%;
      max-width: 500px;
      background: #DADADA;
      display: flex;
      overflow: auto;
    }
    .box {
      width: 200px;
      height: 40px;
      margin: 4px 10px;
      background: red;
      flex-shrink: 0;
    }
    <div class="row">
      <div class="box">1</div>
      <div class="box">2</div>
      <div class="box">3</div>
      <div class="box">4</div>
      <div class="box">5</div>
      <div class="box">6</div>
    </div>