Search code examples
htmlcssgrid-layout

Independent cell width within a grid layout


Is it possible to have independent cell widths within a grid layout in CSS?

I'd like to have the following layout:

+-----------+---------------+-------+
|           |               |   A   |
|           +---------------+-------+
|           |                       |
|           +-------------------+---+
|           |                   | B |
+-----------+-------------------+---+

Please, note that cells A and B are of different width.

In addition for cells A and B being of different size, I'd need cell A to be as large as its content while cell B has an static size.

So far I have this code:

<article class="grid grid-cols-3 grid-rows-3 h-106">
  <div class="row-span-3" />
  <div />
  <div>A</div>
  <div class="col-span-2" />
  <div />
  <div>B</div>
</article>

This piece of code renders the table as shown but with cells A and B bonded together.

I've been searching on internet but I can't seem to find any CSS property that would allow me to do so. I've also been thinking on potential alternatives and I've come with a couple:

  • Make the grid to have 2 columns only and use flex layout inside the upper and lower cells.
  • Make the grid to have 4 columns where the last one is fixed to the size of cell B and the the 3rd one is used to add space to cell A (a col-span).

I'm not sure either of those approaches work or if there is a better one.

Thank you!


Solution

  • Since a grid container uses tracks to align its children, I'd use flexbox in the elements containing A and B. See below.

    .container {
      display: grid;
      grid-template-columns: fit-content(2ch) 1fr;
      grid-auto-rows: 1fr;
      gap: 0.5rem;
    }
    
    .container > div {
      outline: 1px solid lightgray;
    }
    
    .lhs {
      grid-row: 1 / span 3;
      width: 100px;
    }
    
    .one, .three {
      display: flex;
    }
    
    :where(.one, .three) > div {
      flex-grow:1;
    }
    
    .one > div:last-child {
      flex-grow:0;
      background-color: goldenrod;
    }
    
    .three > div:last-child {
      flex-grow: 0;
      width: 100px;
      background-color: cyan;
    }
    <article class="container">
      <div class='lhs'></div>
      <div class='one'>
        <div></div>
        <div>A</div>
      </div>
      <div class="two"></div>
      <div class="three">
        <div></div>
        <div>B</div>
      </div>
    </article>