skip to Main Content

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>

2

Answers


  1. 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>
    Login or Signup to reply.
  2. 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>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search