Search code examples
csscss-grid

How to control the gaps between different size grid items?


In the following layout, I would like A and B to be juxtaposed, and all the gap forced by D be between B & C. Justify/align-content/self/items don't seem to have any effect. Nor does grid-gap.

While these items have fixed sizes, the general problem does not: the items may have various widths. When D is narrower than A + B, they are juxtaposed, but when D is wider than A + B, I can't figure out how to keep A and B juxtaposed.

.container {
  display: grid;
  grid-template-areas: "a b c" "d d e";
  width: min-content;
  background-color: lightyellow;
}

.a {
  grid-area: a;
  width: 120px;
}

.b {
  grid-area: b;
  width: 40px;
}

.c {
  grid-area: c;
  width: 80px;
}

.d {
  grid-area: d;
  width: 300px;
}

.e {
  grid-area: e;
  width: 100px;
}

.a,
.b,
.c,
.d,
.e {
  justify-self: start;
  border: solid 1px black;
  background-color: lightblue;
  height: 40px;
}
<h1>floating grid items</h1>
<div class=container>
  <div class=a>A</div>
  <div class=b>B</div>
  <div class=c>C</div>
  <div class=d>D</div>
  <div class=e>E</div>
</div>


Solution

  • Consider a template column where you set the first one to auto and the second one to 1fr. You can also consider inline-grid instead of setting the width to min-content

    .container {
      display: inline-grid;
      grid-template-areas: 
        "a b c" 
        "d d e";
      grid-template-columns:auto 1fr auto;
      background-color: lightyellow;
      border:1px solid red;
    }
    
    .a {
      grid-area: a;
      width: 120px;
    }
    
    .b {
      grid-area: b;
      width: 40px;
    }
    
    .c {
      grid-area: c;
      width: 80px;
    }
    
    .d {
      grid-area: d;
      width: 300px;
    }
    
    .e {
      grid-area: e;
      width: 100px;
    }
    
    .a,
    .b,
    .c,
    .d,
    .e {
      justify-self: start;
      border: solid 1px black;
      background-color: lightblue;
      height: 40px;
    }
    <h1>floating grid items</h1>
    <div class=container>
      <div class=a>A</div>
      <div class=b>B</div>
      <div class=c>C</div>
      <div class=d>D</div>
      <div class=e>E</div>
    </div>

    Or you can consider max-content in the width and keep display:grid

    .container {
      display: grid;
      grid-template-areas: 
        "a b c" 
        "d d e";
      grid-template-columns:auto 1fr auto;
      background-color: lightyellow;
      border:1px solid red;
      width:max-content;
    }
    
    .a {
      grid-area: a;
      width: 120px;
    }
    
    .b {
      grid-area: b;
      width: 40px;
    }
    
    .c {
      grid-area: c;
      width: 80px;
    }
    
    .d {
      grid-area: d;
      width: 300px;
    }
    
    .e {
      grid-area: e;
      width: 100px;
    }
    
    .a,
    .b,
    .c,
    .d,
    .e {
      justify-self: start;
      border: solid 1px black;
      background-color: lightblue;
      height: 40px;
    }
    <h1>floating grid items</h1>
    <div class=container>
      <div class=a>A</div>
      <div class=b>B</div>
      <div class=c>C</div>
      <div class=d>D</div>
      <div class=e>E</div>
    </div>