7

I have a table style that renders fine when its given enough space:

enter image description here

However, when the width of the parent container is not wide enough the table is hidden:

enter image description here

I can fix this by adding display: block on the table. This will add a horizontal scrollbar:

enter image description here

However, this causes the header to not take up available space when the parent container is very wide:

enter image description here

Is there a way I can get the scrollbar to appear when the parent container is too small, get the header to take up the available space and maintain the look and feel of the table?

:root {
  --global-title-color: black;
  --global-content-background-color: lightgreen;
  --global-background-color: lightblue;
  --global-border-color: red;
  --global-border-radius: 5px;
  --global-border-width-1: 1px;
  --global-font-size-1: 20px;
  --global-font-weight-bold: bold;
  --global-space-fixed-2: 5px;
  --global-space-fixed-3: 10px;
}

.container {
  display: block;
  background: yellow;
  resize: horizontal;
  overflow: hidden;
  min-height: 150px;
}

table {
  color: var(--global-title-color);
  background-color: var(--global-content-background-color);
  border-collapse: separate;
  border-color: var(--global-title-color);
  border-style: solid;
  border-radius: var(--global-border-radius);
  border-width: 0 var(--global-border-width-1) var(--global-border-width-1)
    var(--global-border-width-1);
  border-spacing: 0;
  overflow: auto;
  width: 100%;

  thead {
    th {
      color: var(--global-background-color);
      background-color: var(--global-title-color);
      font-weight: var(--global-font-weight-bold);
      font-size: var(--global-font-size-1);
      padding: var(--global-space-fixed-2) var(--global-space-fixed-3);
      vertical-align: bottom;
    }

    th:first-child {
      border-top-left-radius: var(--global-border-radius);
    }

    th:last-child {
      border-top-right-radius: var(--global-border-radius);
    }
  }

  tbody {
    td {
      border-top: var(--global-border-width-1) solid var(--global-border-color);
      min-width: 100px;
      padding: var(--global-space-fixed-2) var(--global-space-fixed-3);
      vertical-align: top;
    }

    tr:nth-child(2n) {
      background-color: var(--global-background-color);
    }

    tr:last-child {
      td:first-child {
        border-bottom-left-radius: var(--global-border-radius);
      }

      td:last-child {
        border-bottom-right-radius: var(--global-border-radius);
      }
    }
  }
}
<div class="container">
  <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Facilis voluptatum inventore iure blanditiis ab ipsum nostrum repellat cum tempore. Quas harum dolores totam voluptatem deserunt et praesentium nihil placeat. Voluptas.</p>
  <table>
    <thead>
      <tr>
        <th>SDK</th>
        <th>Default namespaces</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Microsoft.NET.Sdk</td>
        <td><code class="language-inline-text">System.Collections.Generic</code></td>
      </tr>
      <tr>
        <td>Microsoft.NET.Sdk.Web</td>
        <td><code class="language-inline-text">System.Net.Http.Json</code></td>
      </tr>

    </tbody>
  </table>
  <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Facilis voluptatum inventore iure blanditiis ab ipsum nostrum repellat cum tempore. Quas harum dolores totam voluptatem deserunt et praesentium nihil placeat. Voluptas.</p>
</div>

All code is also available in the CodePen below:

https://codepen.io/muhammadrehansaeed/pen/JjydLVV?editors=1100

Muhammad Rehan Saeed
  • 35,627
  • 39
  • 202
  • 311

2 Answers2

6

Try this solution with the table display: block; I know you want to avoid using display: block;, but for the scroll, must be a static container. As you mentioned above:

However, this causes the header to not take up available space when the parent container is very wide

To fix this you can set the header cell width: 0.1%.

th {
  width: 0.1%;
  white-space: nowrap;
}

:root {
  --global-title-color: black;
  --global-content-background-color: lightgreen;
  --global-background-color: lightblue;
  --global-border-color: red;
  --global-border-radius: 5px;
  --global-border-width-1: 1px;
  --global-font-size-1: 20px;
  --global-font-weight-bold: bold;
  --global-space-fixed-2: 5px;
  --global-space-fixed-3: 10px;
}

.container {
  display: block;
  background: yellow;
  resize: horizontal;
  overflow: hidden;
  min-height: 150px;
}

table {
  display: block;
  color: var(--global-title-color);
  background-color: var(--global-content-background-color);
  border-collapse: separate;
  border-color: var(--global-title-color);
  border-style: solid;
  border-radius: var(--global-border-radius);
  border-width: 0 var(--global-border-width-1) var(--global-border-width-1) var(--global-border-width-1);
  border-spacing: 0;
  overflow: auto;
}

th {
  width: 0.1%;
  white-space: nowrap;
}

th {
  color: var(--global-background-color);
  background-color: var(--global-title-color);
  font-weight: var(--global-font-weight-bold);
  font-size: var(--global-font-size-1);
  padding: var(--global-space-fixed-2) var(--global-space-fixed-3);
  vertical-align: bottom;
  white-space: nowrap;
}

th:first-child {
  border-top-left-radius: var(--global-border-radius);
}

th:last-child {
  border-top-right-radius: var(--global-border-radius);
}

td {
  border-top: var(--global-border-width-1) solid var(--global-border-color);
  /* min-width: 100px; /* /* changed */
  padding: var(--global-space-fixed-2) var(--global-space-fixed-3);
  vertical-align: top;
}

tr:nth-child(2n) {
  background-color: var(--global-background-color);
}

tr:last-child td:first-child {
  border-bottom-left-radius: var(--global-border-radius);
}

tr:last-child td:last-child {
  border-bottom-right-radius: var(--global-border-radius);
}
<div class="container">
      <p>
        Lorem ipsum dolor sit, amet consectetur adipisicing elit. Facilis
        voluptatum inventore iure blanditiis ab ipsum nostrum repellat cum
        tempore. Quas harum dolores totam voluptatem deserunt et praesentium
        nihil placeat. Voluptas.
      </p>
      <table>
        <thead>
          <tr>
            <th>SDK</th>
            <th>Default namespaces</th>
            <th>Values</th>
            <th>Default</th>
            <th>Other stuff</th>
            <th>#</th>
            <th>SDK</th>
            <th>Namespaces</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>Microsoft.NET.Sdk</td>
            <td>
              <code class="language-inline-text"
                >System.Collections.Generic</code
              >
            </td>
            <td>Values</td>
            <td>
              <code class="language-inline-text">Generic</code>
            </td>
            <td>Microsoft.NET.Sdk</td>
            <td>
              <code class="language-inline-text">00</code>
            </td>
            <td>NET.Sdk</td>
            <td>
              <code class="language-inline-text"
                >System.Collections.Generic</code
              >
            </td>
          </tr>
          <tr>
            <td>Microsoft.NET.Sdk.Web</td>
            <td>
              <code class="language-inline-text">System.Net.Http.Json</code>
            </td>
            <td>Web</td>
            <td>
              <code class="language-inline-text">System.Net.Http.Json</code>
            </td>
            <td>Microsoft.NET.Sdk.Web</td>
            <td>
              <code class="language-inline-text">33</code>
            </td>
            <td>Sdk.Web</td>
            <td>
              <code class="language-inline-text">Http.Json</code>
            </td>
          </tr>
        </tbody>
      </table>
      <p>
        Lorem ipsum dolor sit, amet consectetur adipisicing elit. Facilis
        voluptatum inventore iure blanditiis ab ipsum nostrum repellat cum
        tempore. Quas harum dolores totam voluptatem deserunt et praesentium
        nihil placeat. Voluptas.
      </p>
    </div>
Anton
  • 8,058
  • 1
  • 9
  • 27
  • Doing this causes all columns to be the same width instead of being sized to the content within them. Is there a way to avoid this? – Muhammad Rehan Saeed Oct 18 '21 at 07:51
  • I added more columns and changed the `width: 0.1%` in snippet. The columns have different widths. – Anton Oct 18 '21 at 08:37
  • That doesn't solve the issue. For example the `#` column needs very little space but takes up more than it needs because you have set a percentage width instead of letting the table be responsive and have each column take up only as much as is needed. – Muhammad Rehan Saeed Oct 18 '21 at 09:59
  • 1
    You have a **td** style with `min-width: 100px;` in that case `#` has not own width. If remove it, width will decrease. Snippet was updated. – Anton Oct 18 '21 at 10:48
2

You can remove display: block; on table and replace overflow: hidden; with overflow: auto; on .container.

:root {
  --global-title-color: black;
  --global-content-background-color: lightgreen;
  --global-background-color: lightblue;
  --global-border-color: red;
  --global-border-radius: 5px;
  --global-border-width-1: 1px;
  --global-font-size-1: 20px;
  --global-font-weight-bold: bold;
  --global-space-fixed-2: 5px;
  --global-space-fixed-3: 10px;
}

.container {
  display: block;
  background: yellow;
  resize: horizontal;
  overflow: auto;
  min-height: 150px;
}

table {
  color: var(--global-title-color);
  background-color: var(--global-content-background-color);
  border-collapse: separate;
  border-color: var(--global-title-color);
  border-style: solid;
  border-radius: var(--global-border-radius);
  border-width: 0 var(--global-border-width-1) var(--global-border-width-1)
    var(--global-border-width-1);
  border-spacing: 0;
  overflow: auto;
  width: 100%;

  thead {
    th {
      color: var(--global-background-color);
      background-color: var(--global-title-color);
      font-weight: var(--global-font-weight-bold);
      font-size: var(--global-font-size-1);
      padding: var(--global-space-fixed-2) var(--global-space-fixed-3);
      vertical-align: bottom;
    }

    th:first-child {
      border-top-left-radius: var(--global-border-radius);
    }

    th:last-child {
      border-top-right-radius: var(--global-border-radius);
    }
  }

  tbody {
    td {
      border-top: var(--global-border-width-1) solid var(--global-border-color);
      min-width: 100px;
      padding: var(--global-space-fixed-2) var(--global-space-fixed-3);
      vertical-align: top;
    }

    tr:nth-child(2n) {
      background-color: var(--global-background-color);
    }

    tr:last-child {
      td:first-child {
        border-bottom-left-radius: var(--global-border-radius);
      }

      td:last-child {
        border-bottom-right-radius: var(--global-border-radius);
      }
    }
  }
}
<div class="container">

<table>
<thead>
<tr>
<th>SDK</th>
<th>Default namespaces</th>
</tr>
</thead>
<tbody>
<tr>
<td>Microsoft.NET.Sdk</td>
<td><code class="language-inline-text">System.Collections.Generic</code></td>
</tr>
<tr>
<td>Microsoft.NET.Sdk.Web</td>
<td><code class="language-inline-text">System.Net.Http.Json</code></td>
</tr>

</tbody>
</table>
  
</div>
Tom
  • 4,972
  • 3
  • 10
  • 28
  • Thanks @Tom, that seems to work but in the real world I need to have the container set to `overflow: hidden` because there is other content in the container too. I've updated the example code with some `p` tags to illustrate this point. – Muhammad Rehan Saeed Oct 13 '21 at 15:03