Solution 1 :

First set your table to display: block then set overflow-x: auto

.Table {
    display: block;
    overflow-x: auto;
    white-space: nowrap;
}

As you are saying the rows squash together when going into responsive view. You can prevent that by giving the TD and the TH elements a min-width to not collapse further then the limit.

This method works. See snippet down below:

Note: I added a td min-width so they don’t shrink down responsively to show how it works.

body {
  margin: 0;
}

.App {
  display: flex;
  flex-direction: row;
  width: 100vw;
}

.Sidebar {
  display: block;
  width: 100px;
  background-color: red;
  flex-grow: 0;
  flex-shrink: 0;
}

.Main {
  display: flex;
  flex-direction: column;
    width: calc(100% - 100px);

  background-color: green;
}

.TitleBar {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}

.TableContainer {
  position: relative;
}

td {
  min-width: 500px;
}

.Table {
  display: block;
  overflow-x: auto;
  white-space: nowrap;
}
<div class="App">
  <div class="Sidebar">Sidebar</div>
  <main class="Main">
    <div class="TitleBar">
      <div>Title</div>
      <div>
        <button>Create</button>
      </div>
    </div>
    <div class="TableContainer">
      <table class="Table">
        <thead>
          <tr>
            <th>Name</th>
            <th>Prop 1</th>
            <th>Prop 2</th>
            <th>Prop 3</th>
            <th>Actions</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>Item 1</td>
            <td>Value 1.a</td>
            <td>Value 1.b</td>
            <td>Value 1.c</td>
            <td>
              <button>Edit</button>
            </td>
          </tr>
          <tr>
            <td>Item 2</td>
            <td>Value 2.a</td>
            <td>Value 2.b</td>
            <td>Value 2.c</td>
            <td>
              <button>Edit</button>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </main>
</div>

JS Fiddle

Hosted example by me:

Solution 2 :

Remove overflow-x: scroll from .TableContainer and add overflow-x: auto to .main class and try.

Solution 3 :

One very simple way to fix this is you can add minimum width of table,
You can not add a scroll in the table itself.

.Table {
  width: 100%;
  table-layout: auto;
  min-width:800px;
}

Problem :

I am trying to create a page layout where I render:

  • A fixed width side bar
  • A main content section with
    • A header row (title + button)
    • A table

The table may hold quite a few columns and I don’t want them to get squished together. Instead, I would like the table to scroll horizontally. However, what ends up happening is that the table expands its container and creates a horizontal scroll on the main layout. The scrollbar doesn’t show up in the table itself.

You can see the code and the problem in action here:

.App {
  display: flex;
  flex-direction: row;
  width: 100%;
}

.Sidebar {
  display: block;
  width: 150px;
  background-color: red;
  flex-grow: 0;
  flex-shrink: 0;
  flex-basis: 150px;
}

.Main {
  display: flex;
  flex-direction: column;
  width: 100%;
  background-color: green;
}

.TitleBar {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}

.TableContainer {
  width: 100%;
  position: relative;
  overflow-x: scroll;
}

.Table {
  width: 100%;
  table-layout: auto;
}
<div class="App">
  <div class="Sidebar">Sidebar</div>
  <main class="Main">
    <div class="TitleBar">
      <div>Title</div>
      <div>
        <button>Create</button>
      </div>
    </div>
    <div class="TableContainer">
      <table class="Table">
        <thead>
          <tr>
            <th>Name</th>
            <th>Prop 1</th>
            <th>Prop 2</th>
            <th>Prop 3</th>
            <th>Actions</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>Item 1</td>
            <td>Value 1.a</td>
            <td>Value 1.b</td>
            <td>Value 1.c</td>
            <td>
              <button>Edit</button>
            </td>
          </tr>
          <tr>
            <td>Item 2</td>
            <td>Value 2.a</td>
            <td>Value 2.b</td>
            <td>Value 2.c</td>
            <td>
              <button>Edit</button>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </main>
</div>

Comments

Comment posted by How do I create an HTML table with a fixed/frozen left column and a scrollable body?

Does this answer your question?

Comment posted by jsfiddle.net/dsaltares/egf7238z/14

Thanks, but that doesn’t solve the problem either. The

Comment posted by FUZIION

Add it to the table not the .main container

Comment posted by FUZIION

Edited answer, inserted a snippet showing the scroll.

Comment posted by loom.com/share/9dfda5e551d24ccab3d890dbef9a8763

Still not quite right. See here:

Comment posted by FUZIION

that scrollbar is part of the snippet, insert it into your site and you’ll see.

Comment posted by jsfiddle.net/dsaltares/egf7238z/9

Thanks but that doesn’t work as it makes the

Comment posted by jsfiddle.net/dsaltares/egf7238z/6

Thanks but I don’t think this helps. See for yourself here

By