Search code examples
htmlcsscss-grid

css grid not sizing columns correctly


Just when I think I'm starting to understand this stuff... I'm having trouble with css not sizing my grid columns correctly. The snippet below demonstrates the issue. The grid has 12 columns total. The first row is supposed to be 4, 2, 2, 2, 2 = 12. The second row should be 3, 3, 3, 3 = 12.

The second row columns should all be the same width, but css is rendering the first two columns such that the text ends at "I1234" and the second two such that the text ends at "K1234" - so they are obviously not equal. Interestingly, they do size correctly if I get rid of the first row.

I'm developing this app for Chrome but the same issue happens with Firefox as well.

What am I doing wrong? Thanks - Jon

.test-grid {
    display: grid; 
    gap: 5px;
    grid-template-areas: 
    "a a a a b b c c d d e e"
    "f f f g g g h h h i i i";
}

.a { grid-area: a; }
.b { grid-area: b; }
.c { grid-area: c; }
.d { grid-area: d; }
.e { grid-area: e; }
.f { grid-area: f; }
.g { grid-area: g; }
.h { grid-area: h; }
.i { grid-area: i; }

input {
    width: 100%;
}


<div class="test-grid">

    <div class="a"><input type="text" value="A1234 B1234 C1234 D1234 E1234 F1234 G1234 H1234 I1234 J1234 K1234"></div>
    <div class="b"><input type="text" value="A1234 B1234 C1234 D1234 E1234 F1234 G1234 H1234 I1234 J1234 K1234"></div>
    <div class="c"><input type="text" value="A1234 B1234 C1234 D1234 E1234 F1234 G1234 H1234 I1234 J1234 K1234"></div>
    <div class="d"><input type="text" value="A1234 B1234 C1234 D1234 E1234 F1234 G1234 H1234 I1234 J1234 K1234"></div>
    <div class="e"><input type="text" value="A1234 B1234 C1234 D1234 E1234 F1234 G1234 H1234 I1234 J1234 K1234"></div>
    <div class="f"><input type="text" value="A1234 B1234 C1234 D1234 E1234 F1234 G1234 H1234 I1234 J1234 K1234"></div>
    <div class="g"><input type="text" value="A1234 B1234 C1234 D1234 E1234 F1234 G1234 H1234 I1234 J1234 K1234"></div>
    <div class="h"><input type="text" value="A1234 B1234 C1234 D1234 E1234 F1234 G1234 H1234 I1234 J1234 K1234"></div>
    <div class="i"><input type="text" value="A1234 B1234 C1234 D1234 E1234 F1234 G1234 H1234 I1234 J1234 K1234"></div>

</div>

Solution

  • CSS Grid columns/rows are not independent of each other, the Rows will affect each other naturally.

    You have 5 grid items in the first row, and 4 in the second row, The numbers are not even so the browser will try to even them up and since you didn't tell it how, it will defer to auto.

    The left over space to be shared between the grid items will differ between the two rows and that's why the grid items are not equal widths.

    The calculation goes as follow, given the container width is 1200px and content (in this case input) width is 143px

    1. 143 * 5 = 715px multiply by how many inputs are there to get initial width
    2. 1200 - 715 = 485px subtract initial width from the container width to get left over space
    3. 485 / 12 = 40.416666666666664px divide left over space by 12 desired column count

    At this point the columns width is defined based on 5 input initial width whiel the second row only have 4, the second row can't change that it will just follow it and the browser will try accommodate it, Hence the uneven widths.


    Solutions

    Size grid items evenly using grid-auto-columns: 1fr; or be more explicit about your columns grid-template-columns:repeat(12,1fr);

    .test-grid {
      display: grid;
      grid-gap: 5px;
      grid-auto-columns: 1fr;
      grid-template-areas: "a a a a b b c c d d e e" "f f f g g g h h h i i i";
    }
    
    .test-grid>div {
      height: 100px;
      overflow:hidden; /* small screen sake, not needed */
    }
    
    .a {
      grid-area: a;
      background: red;
    }
    
    .b {
      grid-area: b;
      background: yellow;
    }
    
    .c {
      grid-area: c;
      background: black;
    }
    
    .d {
      grid-area: d;
      background: brown;
    }
    
    .e {
      grid-area: e;
      background: indigo;
    }
    
    .f {
      grid-area: f;
      background: pink;
    }
    
    .g {
      grid-area: g;
      background: green;
    }
    
    .h {
      grid-area: h;
      background: blue;
    }
    
    .i {
      grid-area: i;
      background: orange;
    }
    <div class="test-grid">
      <div class="a"><input type="text" value="A1234 B1234 C1234 D1234 E1234 F1234 G1234 H1234 I1234 J1234 K1234"></div>
      <div class="b"><input type="text" value="A1234 B1234 C1234 D1234 E1234 F1234 G1234 H1234 I1234 J1234 K1234"></div>
      <div class="c"><input type="text" value="A1234 B1234 C1234 D1234 E1234 F1234 G1234 H1234 I1234 J1234 K1234"></div>
      <div class="d"><input type="text" value="A1234 B1234 C1234 D1234 E1234 F1234 G1234 H1234 I1234 J1234 K1234"></div>
      <div class="e"><input type="text" value="A1234 B1234 C1234 D1234 E1234 F1234 G1234 H1234 I1234 J1234 K1234"></div>
      <div class="f"><input type="text" value="A1234 B1234 C1234 D1234 E1234 F1234 G1234 H1234 I1234 J1234 K1234"></div>
      <div class="g"><input type="text" value="A1234 B1234 C1234 D1234 E1234 F1234 G1234 H1234 I1234 J1234 K1234"></div>
      <div class="h"><input type="text" value="A1234 B1234 C1234 D1234 E1234 F1234 G1234 H1234 I1234 J1234 K1234"></div>
      <div class="i"><input type="text" value="A1234 B1234 C1234 D1234 E1234 F1234 G1234 H1234 I1234 J1234 K1234"></div>
    </div>