Arnaud Denoyelle
Arnaud Denoyelle

Reputation: 31235

Scrollbar needed on flex item, not main container

I have a left menu which has a fixed size and a main part which should take the remaining place and contain a table. A scrollbar must appear if the table is too large.

In order to achieve this, I use a flex-box and it works well :

enter image description here

See the code snippet :

.h-container {
  display: flex;
  flex-direction: row;
}

.left-container {
  width: 300px;
  background-color: lightgray;
}

.container {
  overflow-x:auto;
  flex: 1;
}
<div class="h-container">

  <div class="left-container">Left menu</div>

  <div class="container">
    <table>
      <thead>
        <th>Column 1</th>
        <th>Column 2</th>
        <th>Column 3</th>
        <th>Column 4</th>
        <th>Column 5</th>
        <th>Column 6</th>
        <th>Column 7</th>
        <th>Column 8</th>
        <th>Column 9</th>
        <th>Column 10</th>
        <th>Column 11</th>
        <th>Column 12</th>
        <th>Column 13</th>
        <th>Column 14</th>
        <th>Column 15</th>
        <th>Column 16</th>
        <th>Column 17</th>
        <th>Column 18</th>
        <th>Column 19</th>
        <th>Column 20</th>
      </thead>
      <tbody>
        <tr>
          <td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td>
          <td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td><td>19</td><td>20</td>
        </tr>
        <tr>
          <td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td>
          <td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td><td>19</td><td>20</td>
        </tr>
        <tr>
          <td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td>
          <td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td><td>19</td><td>20</td>
        </tr>
        <tr>
          <td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td>
          <td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td><td>19</td><td>20</td>
        </tr>
        <tr>
          <td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td>
          <td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td><td>19</td><td>20</td>
        </tr>
      </tbody>

    </table>
    </div>

</div>

Now, I am trying to insert a banner at the top of the table. In order to achieve this, I wanted to use another flex-box (a vertical flex-box nested in the horizontal flex-box).

Problem : the <table> does not take 100% of its container's width anymore. Instead, it increases the size of its container in order to fit into it without scroll bars. Because of that, a new scroll bar appear on the main container.

enter image description here

See the code snippet :

.h-container {
  display: flex;
  flex-direction: row;
}

.left-container {
  width: 300px;
  flex-shrink:0;
  background-color: lightgray;
}

.v-container {
  flex: 1;
}

.banner {
  height: 50px;
  background-color: lightgreen;
}

.container {
  overflow-x:auto;
  flex:1;
}
<div class="h-container">

  <div class="left-container">Left menu</div>

  <div class="v-container">
  
    <div class="banner">
    Banner
    </div>
  
    <div class="container">
      <table>
        <thead>
          <th>Column 1</th>
          <th>Column 2</th>
          <th>Column 3</th>
          <th>Column 4</th>
          <th>Column 5</th>
          <th>Column 6</th>
          <th>Column 7</th>
          <th>Column 8</th>
          <th>Column 9</th>
          <th>Column 10</th>
          <th>Column 11</th>
          <th>Column 12</th>
          <th>Column 13</th>
          <th>Column 14</th>
          <th>Column 15</th>
          <th>Column 16</th>
          <th>Column 17</th>
          <th>Column 18</th>
          <th>Column 19</th>
          <th>Column 20</th>
        </thead>
        <tbody>
          <tr>
            <td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td>
            <td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td><td>19</td><td>20</td>
          </tr>
          <tr>
            <td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td>
            <td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td><td>19</td><td>20</td>
          </tr>
          <tr>
            <td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td>
            <td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td><td>19</td><td>20</td>
          </tr>
          <tr>
            <td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td>
            <td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td><td>19</td><td>20</td>
          </tr>
          <tr>
            <td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td>
            <td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td><td>19</td><td>20</td>
          </tr>
        </tbody>

      </table>
      </div>
    </div>

</div>

Any ideas?

Upvotes: 1

Views: 86

Answers (3)

Michael Benjamin
Michael Benjamin

Reputation: 371391

Solution

Add min-width: 0 to .v-container (demo).

Tested in Chrome, FF and IE11.


Explanation

You're bumping up against the implied minimum sizing algorithm of flex items.

This is a default setting that prevents a flex item from shrinking past the size of its content.

The defaults are...

  • min-height: auto
  • min-width: auto

...for flex items in column-direction and row-direction, respectively.

You can override these settings with:

  • min-height: 0
  • min-width: 0

From the spec:

4.5. Implied Minimum Size of Flex Items

To provide a more reasonable default minimum size for flex items, this specification introduces a new auto value as the initial value of the min-width and min-height properties defined in CSS 2.1... read more


.h-container {
    display: flex;
    flex-direction: row;
}

.left-container {
    flex: 0 0 300px;
    background-color: lightgray;
}

.v-container {
  flex: 1;
  min-width: 0;  /* NEW */
}


.banner {
    height: 50px;
    background-color: lightgreen;
}

.container {
    overflow-x: auto;
    flex: 1;
}
<div class="h-container">
    <div class="left-container">Left menu</div>
    <div class="v-container">
        <div class="banner">Banner</div>
        <div class="container">
            <table>
                <thead>
                    <th>Column 1</th>
                    <th>Column 2</th>
                    <th>Column 3</th>
                    <th>Column 4</th>
                    <th>Column 5</th>
                    <th>Column 6</th>
                    <th>Column 7</th>
                    <th>Column 8</th>
                    <th>Column 9</th>
                    <th>Column 10</th>
                    <th>Column 11</th>
                    <th>Column 12</th>
                    <th>Column 13</th>
                    <th>Column 14</th>
                    <th>Column 15</th>
                    <th>Column 16</th>
                    <th>Column 17</th>
                    <th>Column 18</th>
                    <th>Column 19</th>
                    <th>Column 20</th>
                </thead>
                <tbody>
                    <tr>
                        <td>1</td>
                        <td>2</td>
                        <td>3</td>
                        <td>4</td>
                        <td>5</td>
                        <td>6</td>
                        <td>7</td>
                        <td>8</td>
                        <td>9</td>
                        <td>10</td>
                        <td>11</td>
                        <td>12</td>
                        <td>13</td>
                        <td>14</td>
                        <td>15</td>
                        <td>16</td>
                        <td>17</td>
                        <td>18</td>
                        <td>19</td>
                        <td>20</td>
                    </tr>
                    <tr>
                        <td>1</td>
                        <td>2</td>
                        <td>3</td>
                        <td>4</td>
                        <td>5</td>
                        <td>6</td>
                        <td>7</td>
                        <td>8</td>
                        <td>9</td>
                        <td>10</td>
                        <td>11</td>
                        <td>12</td>
                        <td>13</td>
                        <td>14</td>
                        <td>15</td>
                        <td>16</td>
                        <td>17</td>
                        <td>18</td>
                        <td>19</td>
                        <td>20</td>
                    </tr>
                    <tr>
                        <td>1</td>
                        <td>2</td>
                        <td>3</td>
                        <td>4</td>
                        <td>5</td>
                        <td>6</td>
                        <td>7</td>
                        <td>8</td>
                        <td>9</td>
                        <td>10</td>
                        <td>11</td>
                        <td>12</td>
                        <td>13</td>
                        <td>14</td>
                        <td>15</td>
                        <td>16</td>
                        <td>17</td>
                        <td>18</td>
                        <td>19</td>
                        <td>20</td>
                    </tr>
                    <tr>
                        <td>1</td>
                        <td>2</td>
                        <td>3</td>
                        <td>4</td>
                        <td>5</td>
                        <td>6</td>
                        <td>7</td>
                        <td>8</td>
                        <td>9</td>
                        <td>10</td>
                        <td>11</td>
                        <td>12</td>
                        <td>13</td>
                        <td>14</td>
                        <td>15</td>
                        <td>16</td>
                        <td>17</td>
                        <td>18</td>
                        <td>19</td>
                        <td>20</td>
                    </tr>
                    <tr>
                        <td>1</td>
                        <td>2</td>
                        <td>3</td>
                        <td>4</td>
                        <td>5</td>
                        <td>6</td>
                        <td>7</td>
                        <td>8</td>
                        <td>9</td>
                        <td>10</td>
                        <td>11</td>
                        <td>12</td>
                        <td>13</td>
                        <td>14</td>
                        <td>15</td>
                        <td>16</td>
                        <td>17</td>
                        <td>18</td>
                        <td>19</td>
                        <td>20</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
</div>

Upvotes: 1

user4994625
user4994625

Reputation:

You can do another flexbox in the right div but in columns:

.h-container {
  display: flex;
  flex-direction: row;
}

.left-container {
  width: 300px;
  flex-shrink:0;
  background-color: lightgray;
}

.v-container {
  flex: 1;
  overflow-x:auto;
  display:flex;
  flex-direction:column;
}

.banner {
  height: 50px;
  background-color: lightgreen;
}

.container {
  overflow-x:auto;
  flex:1;
}
<div class="h-container">

  <div class="left-container">Left menu</div>

  <div class="v-container">
  
    <div class="banner">
    Banner
    </div>
  
    <div class="container">
      <table>
        <thead>
          <th>Column 1</th>
          <th>Column 2</th>
          <th>Column 3</th>
          <th>Column 4</th>
          <th>Column 5</th>
          <th>Column 6</th>
          <th>Column 7</th>
          <th>Column 8</th>
          <th>Column 9</th>
          <th>Column 10</th>
          <th>Column 11</th>
          <th>Column 12</th>
          <th>Column 13</th>
          <th>Column 14</th>
          <th>Column 15</th>
          <th>Column 16</th>
          <th>Column 17</th>
          <th>Column 18</th>
          <th>Column 19</th>
          <th>Column 20</th>
        </thead>
        <tbody>
          <tr>
            <td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td>
            <td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td><td>19</td><td>20</td>
          </tr>
          <tr>
            <td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td>
            <td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td><td>19</td><td>20</td>
          </tr>
          <tr>
            <td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td>
            <td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td><td>19</td><td>20</td>
          </tr>
          <tr>
            <td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td>
            <td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td><td>19</td><td>20</td>
          </tr>
          <tr>
            <td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td>
            <td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td><td>19</td><td>20</td>
          </tr>
        </tbody>

      </table>
      </div>
    </div>

</div>

Upvotes: 1

eye-wonder
eye-wonder

Reputation: 1193

What about using calc(100% - 300px) on the v-container and 100% width on the container.

.h-container {
  display: flex;
  flex-direction: row;
}

.left-container {
  width: 300px;
  flex-shrink:0;
  background-color: lightgray;
}

.v-container {
  /* flex: 1; */
  width: calc(100% - 300px);
}

.banner {
  height: 50px;
  background-color: lightgreen;
}

.container {
  overflow-x:auto;
  /* flex:1;*/
  width:100%;
}
<div class="h-container">

  <div class="left-container">Left menu</div>

  <div class="v-container">
  
    <div class="banner">
    Banner
    </div>
  
    <div class="container">
      <table>
        <thead>
          <th>Column 1</th>
          <th>Column 2</th>
          <th>Column 3</th>
          <th>Column 4</th>
          <th>Column 5</th>
          <th>Column 6</th>
          <th>Column 7</th>
          <th>Column 8</th>
          <th>Column 9</th>
          <th>Column 10</th>
          <th>Column 11</th>
          <th>Column 12</th>
          <th>Column 13</th>
          <th>Column 14</th>
          <th>Column 15</th>
          <th>Column 16</th>
          <th>Column 17</th>
          <th>Column 18</th>
          <th>Column 19</th>
          <th>Column 20</th>
        </thead>
        <tbody>
          <tr>
            <td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td>
            <td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td><td>19</td><td>20</td>
          </tr>
          <tr>
            <td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td>
            <td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td><td>19</td><td>20</td>
          </tr>
          <tr>
            <td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td>
            <td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td><td>19</td><td>20</td>
          </tr>
          <tr>
            <td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td>
            <td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td><td>19</td><td>20</td>
          </tr>
          <tr>
            <td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td>
            <td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td><td>19</td><td>20</td>
          </tr>
        </tbody>

      </table>
      </div>
    </div>

</div>

Upvotes: 1

Related Questions