flexbox width inside horizontally scrollable container

Viewed 229

I am trying to create a layout for a virtual table. A virtual table will be placed inside .table-body element. Each table cell has the same flex layout styles as cells in .table-header so with the same parent element with they would look the same. The problem is that the .table-cell elements do not stretch .table-header width, and .table-header element does not stretch the .table-container width.

I'm trying to get the .table-cell's to give the width for the .table-header and .table-container. And the .table-body would take up the remaining space in the .table-container

Here is Codesandbox to play with.

.table-wrapper {
  width: 500px;
  height: 300px;
  overflow-x: scroll;
  background: rgba(255, 255, 0, 0.2);
}

.table-container {
  display: flex;
  flex-flow: column nowrap;
  width: 100%;
  height: 100%;
  
  /* If you uncomment next line, you see what I'm trying to achieve */
  /* min-width: 1100px; */
  
  background: rgba(0, 255, 0, 0.3);
}

.table-header {
  display: flex;
  flex-flow: row nowrap;
  width: 100%;
  flex: 0 0 auto;
  
  background: rgba(255, 100, 0, 0.3);
}

.table-cell {
  min-width: 100px;
  display: flex;
  flex: 1 1 auto;
  height: 30px;
  line-height: 30px;
  
  border: 1px solid blue;
}

.table-body {
  display: flex;
  flex: 1 1 auto;
  
  border: 1px solid red;
  background: rgba(255, 0, 0, 0.3);
}
<div class="table-wrapper">
  <div class="table-container">
    <div class="table-header">
      <div class="table-cell" style="flex: 0 0 180px;">header-cell 1</div>
      <div class="table-cell">header-cell 2</div>
      <div class="table-cell">header-cell 3</div>
      <div class="table-cell">header-cell 4</div>
      <div class="table-cell" style="flex: 0 0 200px;">header-cell 5</div>
      <div class="table-cell">header-cell 6</div>
      <div class="table-cell">header-cell 7</div>
    </div>
    <div class="table-body">virtual table here</div>
  </div>
</div>

2 Answers

Consider the use of inline-flex instead of flex and define the width using width and not flex-basis

.table-wrapper {
  width: 500px;
  height: 300px;
  overflow-x: scroll;
  background: rgba(255, 255, 0, 0.2);
}

.table-container {
  display: inline-flex; /* UPDATED */
  flex-flow: column nowrap;
  min-width: 100%; /* UPDATED */
  height: 100%;
  background: rgba(0, 255, 0, 0.3);
}

.table-header {
  display: flex;
  flex-flow: row nowrap;
  width: 100%;
  flex: 0 0 auto;
  
  background: rgba(255, 100, 0, 0.3);
}

.table-cell {
  min-width: 100px;
  display: flex;
  flex: 1 1 auto;
  height: 30px;
  line-height: 30px;
  
  border: 1px solid blue;
}

.table-body {
  display: flex;
  flex: 1 1 auto;
  
  border: 1px solid red;
  background: rgba(255, 0, 0, 0.3);
}
<div class="table-wrapper">
  <div class="table-container">
    <div class="table-header">
      <div class="table-cell" style="flex: 0 0 180px;width:180px;">header-cell 1</div>
      <div class="table-cell">header-cell 2</div>
      <div class="table-cell">header-cell 3</div>
      <div class="table-cell">header-cell 4</div>
      <div class="table-cell" style="flex: 0 0 200px;width:200px;">header-cell 5</div>
      <div class="table-cell">header-cell 6</div>
      <div class="table-cell">header-cell 7</div>
    </div>
    <div class="table-body">virtual table here</div>
  </div>
</div>

Here's a workaround I found, use width: min-content; for both table-header and table-container.
This only work when you get rid of the inline style in the table-cell.

.table-wrapper {
  width: 500px;
  height: 300px;
  overflow-x: scroll;
  background: rgba(255, 255, 0, 0.2);
}

.table-container {
  display: flex;
  flex-flow: column nowrap;
  width: min-content;
  height: 100%;
  
  /* If you uncomment next line, you see what I'm trying to achieve */
  /* min-width: 1100px; */
  
  background: rgba(0, 255, 0, 0.3);
}

.table-header {
  display: flex;
  flex-flow: row nowrap;
  width: min-content;
  flex: 0 0 auto;
  
  background: rgba(255, 100, 0, 0.3);
}

.table-cell {
  min-width: 100px;
  display: flex;
  flex: 1 1 auto;
  height: 30px;
  line-height: 30px;
  
  border: 1px solid blue;
}

.table-body {
  display: flex;
  flex: 1 1 auto;
  
  border: 1px solid red;
  background: rgba(255, 0, 0, 0.3);
}
<div class="table-wrapper">
  <div class="table-container">
    <div class="table-header">
      <div class="table-cell">header-cell 1</div>
      <div class="table-cell">header-cell 2</div>
      <div class="table-cell">header-cell 3</div>
      <div class="table-cell">header-cell 4</div>
      <div class="table-cell" >header-cell 5</div>
      <div class="table-cell">header-cell 6</div>
      <div class="table-cell">header-cell 7</div>
    </div>
    <div class="table-body">virtual table here</div>
  </div>
</div>

Related