Mike
Mike

Reputation: 151

Flexbox child is growing outside its parent

I use flexbox all of the time, but for some reason, this has had me scratching my head for a couple of days.

What I'm looking for is the cyan-colored area to be XY-scrollable (.scrollable), with the magenta (.tab-content) padding around it.

The lowest item that seems to have it together is the blue (.panels) div, which knows it should be window width and 200px high. Then the flex child .body just grows off of the screen.

It seems like the problem is that .body can't figure out how wide the parent .panels is. I've never had an issue like this, and I'm pretty sure it revolves around not being able to wrap the text in the cyan table, but I have to have those as individual lines.

Chrome 48 (version mandated): enter image description here

* {
  box-sizing: border-box;
}
.detail {} .panels {
  background-color: blue;
  display: flex;
  max-height: 200px;
}
.header {
  background-color: red;
  margin-right: 1rem;
  flex-shrink: 0;
}
.body {
  background-color: green;
  display: flex;
  flex-direction: column;
  flex: 1;
}
.tabs {
  flex-shrink: 0;
}
.tab-content {
  flex: 1;
  background-color: magenta;
  padding: 1rem;
}
.scrollable {
  overflow: auto;
  background-color: cyan;
}
.formatted-text {
  white-space: pre;
}
<div class="detail">
  <div class="panels">
    <div class="header">
      <table>
        <tr>
          <td>Field</td>
          <td>Value</td>
        </tr>
        <tr>
          <td>Field</td>
          <td>Value</td>
        </tr>
        <tr>
          <td>Field</td>
          <td>Value</td>
        </tr>
        <tr>
          <td>Field</td>
          <td>Value</td>
        </tr>
      </table>
    </div>
    <div class="body">
      <div class="tabs">Tabs</div>
      <div class="tab-content">
        <div class="scrollable">
          <table>
            <tbody>
              <tr>
                <td>01</td>
                <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
              </tr>
              <tr>
                <td>01</td>
                <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
              </tr>
              <tr>
                <td>01</td>
                <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
              </tr>
              <tr>
                <td>01</td>
                <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
              </tr>
              <tr>
                <td>01</td>
                <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
              </tr>
              <tr>
                <td>01</td>
                <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
              </tr>
              <tr>
                <td>01</td>
                <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
              </tr>
              <tr>
                <td>01</td>
                <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
              </tr>
              <tr>
                <td>01</td>
                <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
              </tr>
              <tr>
                <td>01</td>
                <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
    </div>
  </div>
</div>

Codepen here: http://codepen.io/anon/pen/BjvWzR

Upvotes: 1

Views: 1414

Answers (2)

schuno
schuno

Reputation: 585

I copied your code into an .html file and tested it out and it is working as you are expecting. My guess is your issues are caused by other css passed down from some parent components on your page.

Here is the combination of your css and html above that I ran to get the successful result:

<html>
<head>
    <style type="text/css">
        * {
          box-sizing: border-box;
        }
        .detail {} .panels {
          background-color: blue;
          display: flex;
          max-height: 200px;
        }
        .header {
          background-color: red;
          margin-right: 1rem;
          flex-shrink: 0;
        }
        .body {
          background-color: green;
          display: flex;
          flex-direction: column;
          flex: 1;
        }
        .tabs {
          flex-shrink: 0;
        }
        .tab-content {
          flex: 1;
          background-color: magenta;
          padding: 1rem;
        }
        .scrollable {
          overflow: auto;
          background-color: cyan;
        }
        .formatted-text {
          white-space: pre;
        }
    </style>
</head>
<body>
    <div class="detail">
      <div class="panels">
        <div class="header">
          <table>
            <tr>
              <td>Field</td>
              <td>Value</td>
            </tr>
            <tr>
              <td>Field</td>
              <td>Value</td>
            </tr>
            <tr>
              <td>Field</td>
              <td>Value</td>
            </tr>
            <tr>
              <td>Field</td>
              <td>Value</td>
            </tr>
          </table>
        </div>
        <div class="body">
          <div class="tabs">Tabs</div>
          <div class="tab-content">
            <div class="scrollable">
              <table>
                <tbody>
                  <tr>
                    <td>01</td>
                    <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
                  </tr>
                  <tr>
                    <td>01</td>
                    <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
                  </tr>
                  <tr>
                    <td>01</td>
                    <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
                  </tr>
                  <tr>
                    <td>01</td>
                    <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
                  </tr>
                  <tr>
                    <td>01</td>
                    <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
                  </tr>
                  <tr>
                    <td>01</td>
                    <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
                  </tr>
                  <tr>
                    <td>01</td>
                    <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
                  </tr>
                  <tr>
                    <td>01</td>
                    <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
                  </tr>
                  <tr>
                    <td>01</td>
                    <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
                  </tr>
                  <tr>
                    <td>01</td>
                    <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
                  </tr>
                </tbody>
              </table>
            </div>
          </div>
        </div>
      </div>
    </div>
</body>
</html>

Upvotes: 0

Asons
Asons

Reputation: 87191

You need to solve that with position: absolute, like this

.scrollable {
  background-color: cyan;
  position: absolute;
  left: 1rem;
  top:1rem; 
  right: 1rem;
  bottom: 1rem;
  overflow: auto;  
}

Sample snippet

* {
  box-sizing: border-box;
}

.detail {}

.panels {
  background-color: blue;
  display: flex;
  max-height: 200px;
}

.header {
  background-color: red;
  margin-right: 1rem;
  flex-shrink: 0;
}

.body {
  background-color: green;
  display: flex;
  flex-direction: column;
  flex: 1;
}

.tabs {
  flex-shrink: 0;
}

.tab-content {
  flex: 1;
  background-color: magenta;
  padding: 1rem;
  position: relative;
}

.scrollable {
  background-color: cyan;
  position: absolute;
  left: 1rem;
  top:1rem; 
  right: 1rem;
  bottom: 1rem;
  overflow: auto;  
}

.formatted-text {
  white-space: pre;
}
<div class="detail">
  <div class="panels">
    <div class="header">
      <table>
        <tr>
          <td>Field</td>
          <td>Value</td>
        </tr>
        <tr>
          <td>Field</td>
          <td>Value</td>
        </tr>
        <tr>
          <td>Field</td>
          <td>Value</td>
        </tr>
        <tr>
          <td>Field</td>
          <td>Value</td>
        </tr>
        <tr>
          <td>Field</td>
          <td>Value</td>
        </tr>
        <tr>
          <td>Field</td>
          <td>Value</td>
        </tr>
        <tr>
          <td>Field</td>
          <td>Value</td>
        </tr>
        <tr>
          <td>Field</td>
          <td>Value</td>
        </tr>
        <tr>
          <td>Field</td>
          <td>Value</td>
        </tr>
      </table>
    </div>
    <div class="body">
      <div class="tabs">Tabs</div>
      <div class="tab-content">
        <div class="scrollable">
          <table>
            <tbody>
              <tr>
                <td>01</td>
                <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
              </tr>
              <tr>
                <td>01</td>
                <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
              </tr>
              <tr>
                <td>01</td>
                <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
              </tr>
              <tr>
                <td>01</td>
                <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
              </tr>
              <tr>
                <td>01</td>
                <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
              </tr>
              <tr>
                <td>01</td>
                <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
              </tr>
              <tr>
                <td>01</td>
                <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
              </tr>
              <tr>
                <td>01</td>
                <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
              </tr>
              <tr>
                <td>01</td>
                <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
              </tr>
              <tr>
                <td>01</td>
                <td class="formatted-text">THIS IS SOME REALLY, REALLY LONG TEXT THAT REPRESENTS FIXED-WIDTH FILE OUTPUT, SO IT WILL BE IN A MONO FONT AND CANNOT BREAK PER LINE. EACH LINE IS 300 BYTES LONG.</td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
    </div>
  </div>
</div>

Upvotes: 2

Related Questions