Search code examples
csscss-grid

How to target the last column in a CSS grid?


When you use grid-areas the elements may change order. This will cause the visual :last-child to change. Is there a CSS selector to target the last column in a grid instead? Something like :last-grid-column.

The problem I am trying to solve. I like the columns to be separated by a border line. However I don't want the last column to have a border, because that wouldn't make visually sense. Now if I were to target it with :last-child it works until I change the order of the grid-template-areas to something like d b c a. Now the first column would not have a border because in the DOM it's still the last-child.

I understand you can have a work around where you would explicitly say these are the grid areas and I would omit the border for a in this case. But it would be so much more flexible if I could describe it semantically, then I could freely change the template areas without worrying that the border lines will be messed up.

.grid 
{
  display: grid;
  grid-template-areas: "d b c a";
  grid-template-columns: repeat( 4, 1fr );
}

.column.a { 
  grid-area: a; 
}

.column.b { 
  grid-area: b; 
}

.column.c { 
  grid-area: c; 
}

.column.d { 
  grid-area: d; 
}

.column:not(:last-child) {
  border-right: 1px solid black;
}

/* Flavor */
.grid 
{
  margin: 20px auto;
  max-width: 600px;
  padding: 20px;
  background: #F4F4F4;
}

.column { 
  width: 100%; 
  text-align: center;
}
<div class="grid">
  <div class="column a">A</div>
  <div class="column b">B</div>
  <div class="column c">C</div>
  <div class="column d">D</div>
</div>


Solution

  • Such selector exist but we are still far from having a good support for it. You can read:

    To be able to represent such implied column-based relationships, the column combinator and the :nth-col() and :nth-last-col() pseudo-classes are defined

    For your particular case, a background can do the job:

    .grid 
    {
      display: grid;
      grid-template-areas: "d b c a";
      grid-template-columns: repeat( 4, 1fr );
      background:
        linear-gradient(90deg,#0000 calc(100% - 1px), #000 0)
        0 50%/calc((100% + 1px)/4) 50% repeat-x
        #F4F4F4;
    }
    
    .column.a { 
      grid-area: a; 
    }
    
    .column.b { 
      grid-area: b; 
    }
    
    .column.c { 
      grid-area: c; 
    }
    
    .column.d { 
      grid-area: d; 
    }
    
    
    /* Flavor */
    .grid 
    {
      margin: 20px auto;
      max-width: 600px;
      padding: 20px;
    }
    
    .column { 
      width: 100%; 
      text-align: center;
    }
    <div class="grid">
      <div class="column a">A</div>
      <div class="column b">B</div>
      <div class="column c">C</div>
      <div class="column d">D</div>
    </div>