11

The Problem:

In a full-size app layout (100% width, 100% height) using flexbox with overflow, the scrollbars do not display for overflow-y in Firefox, IE, or Edge. They do display properly in Chrome. Rather than having a vertical scrollbar in FF/IE/Edge on the element, the scrollbar is applied to the entire page.

What I've Tried:

I've tried adding, as mentioned in several other SO answers, to add min-height: 0; to the flex elements / parents. I haven't been able to get this solution to work, but perhaps I am doing something wrong.

Screenshots:

Chrome:

enter image description here

Firefox:

enter image description here

Example:

https://codepen.io/gunn4r/pen/WEoPjN

html {
  height: 100%;
}

.flex-grow {
  flex: 1;
}

.canvas-wrapper {
  overflow: scroll;
}

.canvas {
  width: 3000px;
  height: 3000px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet" />

<body class="h-100">
  <div class="h-100 container-fluid d-flex flex-column">

    <div class="row bg-warning">
      <div class="col-12 py-4">Top Bar</div>
    </div>

    <div class="row no-gutter flex-grow">

      <div class="col-9 px-0 d-flex flex-column">
        <div class="canvas-wrapper">
          <div class="canvas bg-success">
            Canvas
          </div>
        </div>
        <div class="bg-danger py-3">
          Canvas Footer
        </div>
      </div>

      <div class="col-3 bg-primary">
        <div class="sidebar-item">Sidebar</div>
      </div>

    </div>

    <div class="row bg-warning">
      <div class="col-12 py-2">Overall Footer</div>
    </div>

  </div>
</body>

0

2 Answers 2

8

It looks like the problem stems from this section of your code:

.canvas-wrapper {
  overflow: scroll;
}

You want this element to have scrollbars. However, the element has no defined height.

From MDN:

In order for overflow to have an effect, the block-level container must have either a set height (height or max-height) or white-space set to nowrap.

Chrome doesn't seem to care about the height requirement. The other browsers do.

This should be enough to make it work across browsers:

.canvas-wrapper {
  overflow: scroll;
  flex: 1 0 1px;
}

html {
  height: 100%;
}

.flex-grow {
  flex: 1;
}

.canvas-wrapper {
  overflow: scroll;
  flex: 1 0 1px; /* NEW */
}

.canvas {
  width: 3000px;
  height: 3000px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
<body class="h-100">
  <div class="h-100 container-fluid d-flex flex-column">

    <div class="row bg-warning">
      <div class="col-12 py-4">Top Bar</div>
    </div>

    <div class="row no-gutter flex-grow">
      
      <div class="col-9 px-0 d-flex flex-column">
         <div class="canvas-wrapper">
             <div class="canvas bg-success">
               Canvas
           </div>
        </div>
        <div class="bg-danger py-3">
          Canvas Footer
        </div>
      </div>
      
      <div class="col-3 bg-primary">
        <div class="sidebar-item">Sidebar</div>
      </div>
      
    </div>

    <div class="row bg-warning">
      <div class="col-12 py-2">Overall Footer</div>
    </div>

    </div>
</body>

Sign up to request clarification or add additional context in comments.

2 Comments

Of course...+1...I tried with flex-grow: 1, which didn't work so went for the absolute position variant
Even better! I appreciate the MDN reference, I missed that part!
3

When using percent for height on element, all its ascendants also need a height set, and if all will have percent, one need to set it all the way up to the html/body.

When combined with Flexbox this can get really tricky to solve, as when one need to set height: 100% on all ascendants, other unwanted render issues can cause the layout to break.

Here is one solution, which work perfect cross browser, where an extra wrapper, canvas-fix, for the canvas is added, and then with position: absolute we can make this work.

Fiddle demo

Stack snippet

html {
  height: 100%;
}
.flex-grow {
  flex: 1;
}
.canvas-wrapper {
  flex-grow: 1;                     /*  take all remaining space  */
  width: 100%;                      /*  full width  */
  position: relative;               /*  for the absolute positioned fix  */
}
.canvas-fix {                       /*  added rule  */
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  overflow: scroll;
}
.canvas {
  width: 3000px;
  height: 3000px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet" />

<body class="h-100">
  <div class="h-100 container-fluid d-flex flex-column">

    <div class="row bg-warning">
      <div class="col-12 py-4">Top Bar</div>
    </div>

    <div class="row no-gutter flex-grow">

      <div class="col-9 px-0 d-flex flex-column">
        <div class="canvas-wrapper">
          <div class="canvas-fix">
            <div class="canvas bg-success">
               Canvas
            </div>
          </div>
        </div>
        <div class="bg-danger py-3">
          Canvas Footer
        </div>
      </div>

      <div class="col-3 bg-primary">
        <div class="sidebar-item">Sidebar</div>
      </div>

    </div>

    <div class="row bg-warning">
      <div class="col-12 py-2">Overall Footer</div>
    </div>

    </div>
</body>

1 Comment

Great answer! I was worried about when increasing height on things like footer dynamically that it would cause issues, but since the absolutely positioned element is nested under the relative element, everything works perfect. You're the man!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.