Search code examples
cssflexboxinternet-explorer-11

How can I work around this IE 11 behaviour where flexbox + inline-block + overflow causes overlap?


I have an IE11 bug which I'm looking to work around somehow.

My setup:

  1. The is a div which I will call outer which has display: flex, flex-direction: column, and width: 100%.
  2. It contains two other divs, which I will call upper and lower.
  3. upper contains a number of inline-block elements – enough to require some wrapping.
  4. lower contains enough other elements to overflow off the bottom of the screen, and so will get a scrollbar.

What I would expect to happen is that upper should be big enough to contain all of the inline-block elements inside it. This works fine in Chrome and Firefox, but in IE11 it isn't tall enough.

This problem also occurs with display: inline, but not with display: block (although I think I definitely need inline-block for my layout).

If I reduce the amount of content inside lower so that it fits on the screen, the problem goes away.

Any assistance greatly appreciated.

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

.outer {
  height: 100%;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.upper {
  margin: 0;
  background-color: pink;
}

.upper div {
  display: inline-block;
  width: 10rem;
  max-width: 10rem;
  color: white;
  background-color: red;
}

.lower {
    overflow-y: auto;
}

.lower p {
  background-color: green;
}
<div class="outer">
  <div class="upper">
    <div>0</div>
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
    <div>6</div>
    <div>7</div>
    <div>8</div>
    <div>9</div>
    <div>10</div>
    <div>11</div>
    <div>12</div>
    <div>13</div>
    <div>14</div>
    <div>15</div>
    <div>16</div>
    <div>17</div>
    <div>18</div>
    <div>19</div>
  </div>

  <div class="lower">
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
  </div>
</div>


Solution

  • Use min-height instead of height when you know that you'll receive overflow.

    I've replaced height: 100% for html, body and .outer with min-height: 100vh only for .outer just for brevity.

    Demo:

    body {
      margin: 0;
    }
    
    .outer {
      min-height: 100vh;
      display: flex;
      flex-direction: column;
    }
    
    .inner {
      margin: 0;
      background-color: pink;
      flex-shrink: 0;
    }
    
    .inner div {
      display: inline-block;
      width: 10rem;
      max-width: 10rem;
      color: white;
      background-color: red;
    }
    
    .outer p {
      background-color: green;
      flex-shrink: 0;
    }
    <div class="outer">
      <div class="inner">
        <div>0</div>
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div>4</div>
        <div>5</div>
        <div>6</div>
        <div>7</div>
        <div>8</div>
        <div>9</div>
        <div>10</div>
        <div>11</div>
        <div>12</div>
        <div>13</div>
        <div>14</div>
        <div>15</div>
        <div>16</div>
        <div>17</div>
        <div>18</div>
        <div>19</div>
      </div>
      
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
    </div>

    If you need to add vertical scrollbar to your .outer when necessary just add overflow-y: auto. Demo:

    body {
      margin: 0;
    }
    
    .outer {
      height: 100vh;
      overflow-y: auto;
      display: flex;
      flex-direction: column;
    }
    
    .inner {
      margin: 0;
      background-color: pink;
      flex-shrink: 0;
    }
    
    .inner div {
      display: inline-block;
      width: 10rem;
      max-width: 10rem;
      color: white;
      background-color: red;
    }
    
    .outer p {
      background-color: green;
      flex-shrink: 0;
    }
    <div class="outer">
      <div class="inner">
        <div>0</div>
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div>4</div>
        <div>5</div>
        <div>6</div>
        <div>7</div>
        <div>8</div>
        <div>9</div>
        <div>10</div>
        <div>11</div>
        <div>12</div>
        <div>13</div>
        <div>14</div>
        <div>15</div>
        <div>16</div>
        <div>17</div>
        <div>18</div>
        <div>19</div>
      </div>
      
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
      <p>Text</p>
    </div>

    Update for new markup

    Just add flex-shrink: 0 for .upper. Demo:

    html,
    body {
      height: 100%;
      margin: 0;
      padding: 0;
    }
    
    .outer {
      height: 100%;
      overflow: hidden;
      display: flex;
      flex-direction: column;
    }
    
    .upper {
      margin: 0;
      background-color: pink;
      flex-shrink: 0;
    }
    
    .upper div {
      display: inline-block;
      width: 10rem;
      max-width: 10rem;
      color: white;
      background-color: red;
    }
    
    .lower {
      overflow-y: auto;
    }
    
    .lower p {
      background-color: green;
    }
    <div class="outer">
      <div class="upper">
        <div>0</div>
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div>4</div>
        <div>5</div>
        <div>6</div>
        <div>7</div>
        <div>8</div>
        <div>9</div>
        <div>10</div>
        <div>11</div>
        <div>12</div>
        <div>13</div>
        <div>14</div>
        <div>15</div>
        <div>16</div>
        <div>17</div>
        <div>18</div>
        <div>19</div>
      </div>
    
      <div class="lower">
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
        <p>Text</p>
      </div>
    </div>