Search code examples
htmlcsscss-tables

CSS to make tables equal height, including stretching their rowspan vertical headers?


I have several tables with a vertical header cell on the left which is set to span across all rows using rowspan.

The vertical header has its own background-color.

I want the tables to all be the same height, including "stretching" the vertical header (or at least stretching its background-color), ideally without editing the HTML markup of the table itself (e.g. adding fake/empty rows), and definitely without JavaScript.

Demo Fiddle: https://jsfiddle.net/97owvn6f/3/

#tables {
  background-color: purple;
}

table {
  display: inline-block;
  background-color: lightblue;
  border-collapse: collapse;
  margin-right: 50px;
}

th,
td {
  padding: 10px;
  vertical-align: top;
}

.vertical-header {
  background-color: pink;
}
<div id="tables">
  <table>
    <tr>
        <th class="vertical-header" rowspan="3">A</th>
        <th colspan="4">My Short Table</th>
    </tr>
    <tr>
        <td>1</td>
        <td>Small widget</td>
    </tr>
    <tr>
        <td>2</td>
        <td>Medium widget</td>
    </tr>
</table>

<table>
    <tr>
        <th class="vertical-header" rowspan="11">B</th>
        <th colspan="3">My Tall Table</th>
    </tr>
    <tr>
        <td>1</td>
        <td>Small widget</td>
    </tr>
    <tr>
        <td>2</td>
        <td>Medium widget</td>
    </tr>
    <tr>
        <td>3</td>
        <td>Other widget</td>
    </tr>
    <tr>
        <td>4</td>
        <td>Other widget</td>
    </tr>
    <tr>
        <td>5</td>
        <td>Other widget</td>
    </tr>
    <tr>
        <td>6</td>
        <td>Other widget</td>
    </tr>
    <tr>
        <td>7</td>
        <td>Other widget</td>
    </tr>
    <tr>
        <td>8</td>
        <td>Other widget</td>
    </tr>
    <tr>
        <td>9</td>
        <td>Other widget</td>
    </tr>
    <tr>
        <td>10</td>
        <td>Other widget</td>
    </tr>
</table>
</div>

What I currently have:
enter image description here

What I want:
enter image description here


Solution

  • display: flex; in the container fixes the height of the tables to fill the available space, the problem is the tbody doesn't stretch to the total height because it only adopts the size of its tr elements.

    A possible workaround is to make the pink stripe with a linear-gradient as background for the tables:

    #tables {
      background-color: purple;
      display: flex;
    }
    
    table {
      border-collapse: collapse;
      margin-right: 50px;
      display: inline-block;
      background: linear-gradient(90deg, pink 0%, pink 34px, lightblue 34px);
      background-size: 100% 100%;
      background-repeat: no-repeat;
    }
    
    th,
    td {
      padding: 10px;
      vertical-align: top;
    }
    
    .vertical-header {
      width: 14px; /* +20px of padding = 34px for the pink stripe */
    }
    <div id="tables">
      <table>
            <tr>
                <th class="vertical-header" rowspan="3">A</th>
                <th colspan="4">My Short Table</th>
            </tr>
            <tr>
                <td>1</td>
                <td>Small widget</td>
            </tr>
            <tr>
                <td>2</td>
                <td>Medium widget</td>
            </tr>
        </table>
    
        <table>
            <tr>
                <th class="vertical-header" rowspan="11">B</th>
                <th colspan="3">My Tall Table</th>
            </tr>
            <tr>
                <td>1</td>
                <td>Small widget</td>
            </tr>
            <tr>
                <td>2</td>
                <td>Medium widget</td>
            </tr>
            <tr>
                <td>3</td>
                <td>Other widget</td>
            </tr>
            <tr>
                <td>4</td>
                <td>Other widget</td>
            </tr>
            <tr>
                <td>5</td>
                <td>Other widget</td>
            </tr>
            <tr>
                <td>6</td>
                <td>Other widget</td>
            </tr>
            <tr>
                <td>7</td>
                <td>Other widget</td>
            </tr>
            <tr>
                <td>8</td>
                <td>Other widget</td>
            </tr>
            <tr>
                <td>9</td>
                <td>Other widget</td>
            </tr>
            <tr>
                <td>10</td>
                <td>Other widget</td>
            </tr>
        </table>
    </div>