Search code examples
htmlcssflexboxcss-grid

Turn a table row in a css grid layout independent from other rows


I've to rearrange a table like this one using only CSS.

<head>
<style>
table, th, td {border: 1px solid black; border-collapse: collapse; }
th, td {padding: 5px;}
th {text-align: left;}
</style>
</head>
<body>

<table>
    <tr>
        <th>H1</th>
	<th>H2</th>
	<th>H3</th>
        <th>H4</th>
	<th>H5</th>
	<th>H6</th>
	<th>H7</th>
	<th>H8</th>
	<th>H9</th>
	<th>H10</th>
    </tr>
    <tr>
	<td class="col-A1">A1</td>
        <td class="col-A2">A2</td>
	<td class="col-A3">A3</td>
	<td class="col-A4">A4</td>
	<td class="col-A5">A5</td>
	<td class="col-A6">A6</td>
	<td class="col-A7">A7</td>
	<td class="col-A8">A8</td>
	<td class="col-A9">A9</td>
	<td class="col-A10">A10</td>
    </tr>
    <tr>
	<td class="col-B1">B1</td>
	<td class="col-B2">B2</td>
	<td class="col-B3">B3</td>
	<td class="col-B4">B4</td>
        <td class="col-B5">B5</td>
	<td class="col-B6">B6</td>
	<td class="col-B7">B7</td>
	<td class="col-B8">B8</td>
	<td class="col-B9">B9</td>
	<td class="col-B10">B10</td>
    </tr>
</table>
</body>

How can I get a layout like this? My initial idea would have been using CSS flexbox but I didn't know how to rearrange the row into this layout, especially the A2 to A7 part in which there are two columns.

So as suggested by comments to original post, I would opt for a CSS grid layout.

Table final layout


Solution

  • This is not possible with tables even if you rearrange the rows because col-A9 and col-A10 occupy 2.5 columns each. And with flexbox you would find difficulty spanning the rows (eg col-A2) and can be solved only if you nest more containers.

    But with css grids this is actually easy - you can use a 20-column layout here. See demo with explanations inline:

    .wrapper {
      display: grid; /* establish a grid container */
      grid-template-columns: repeat(20, 1fr); /* 20 columns */
      grid-auto-rows: 50px; /* row height for illustration */
    }
    
    .wrapper div {
      border: 1px solid;
      grid-column: span 2; /* span two columns */ 
      /* flexbox to center content*/
      display: flex;
      justify-content: center;
      align-items: center;
    }
    
    .wrapper .a {
      grid-column: span 10;  /* span ten columns */ 
    }
    
    .wrapper .a1 {
      grid-column: span 20; /* span all 20 columns */ 
    }
    
    .wrapper .a2 {
      grid-row: span 5; /* span five rows */ 
    }
    
    .wrapper .a9,.wrapper .a10{
      grid-column: span 5; /* span five columns */ 
    }
    <div class="wrapper">
      <div class="h">H1</div>
      <div class="h">H2</div>
      <div class="h">H3</div>
      <div class="h">H4</div>
      <div class="h">H5</div>
      <div class="h">H6</div>
      <div class="h">H7</div>
      <div class="h">H8</div>
      <div class="h">H9</div>
      <div class="h">H10</div>
      
      <div class="a a1">A1</div>
      <div class="a a2">A2</div>
      <div class="a a3">A3</div>
      <div class="a a4">A4</div>
      <div class="a a5">A5</div>
      <div class="a a6">A6</div>
      <div class="a a7">A7</div>
      <div class="a a8">A8</div>
      <div class="a a9">A9</div>
      <div class="a a10">A10</div>
      
      <div class="b">B1</div>
      <div class="b">B2</div>
      <div class="b">B3</div>
      <div class="b">B4</div>
      <div class="b">B5</div>
      <div class="b">B6</div>
      <div class="b">B7</div>
      <div class="b">B8</div>
      <div class="b">B9</div>
      <div class="b">B10</div>
      
    </div>