2

Right now I have a grid with 1 row and 5 columns, which I'm going to be using for navigational links, but there's a chance that on some pages the grid container might not have 5 children.

The issue is that grids begin filling from the first available area.

Is there any way to fill the grid container with grid items so that instead the last area is always filled?

For example...

[a][b][c][d][ ] should be [ ][a][b][c][d]

[a][b][c][ ][ ] should be [ ][ ][a][b][c]

Notably, I do not want to reverse the direction of the elements, but rather keep the elements in the same order all the time.

Is there a simple way to do this without modifying the number of columns?

oldboy
  • 5,729
  • 6
  • 38
  • 86
  • 1
    Is it always going to be 1 row? if so then a flex box looks like a better choice for this. – arieljuod May 12 '19 at 02:15
  • @arieljuod ya it is always going to be one row. flex would def prolly be the better approach, but the reason i went for grid in this instance is because so that the children always assume 1/5th of the width unlike flex, and there will likely be instances whereby there are less than 5 children. – oldboy May 13 '19 at 06:33

1 Answers1

3

Since it's will only be 5 columns you can explicitly define this for each element using nth-last-child()

.grid {
  display:grid;
  grid-template-columns:repeat(5,1fr);
  grid-gap:5px;
  margin:5px;
}
.grid > span {
  padding:10px;
  background:yellow;
  
}

.grid > span:nth-last-child(1) { grid-column:5; }
.grid > span:nth-last-child(2) { grid-column:4; }
.grid > span:nth-last-child(3) { grid-column:3; }
.grid > span:nth-last-child(4) { grid-column:2; }
/*.grid > span:nth-last-child(5) { grid-column:1; } this one is not needed*/
<div class="grid">
<span>a</span>
<span>b</span>
<span>c</span>
<span>d</span>
</div>

<div class="grid">
<span>a</span>
<span>b</span>
</div>

<div class="grid">
<span>a</span>
<span>b</span>
<span>c</span>
<span>d</span>
<span>e</span>
</div>

Or consider flexbox where it will be easier:

.grid {
  display:flex;
  margin:5px;
  justify-content:flex-end;
}
.grid > span {
  padding:10px;
  background:yellow;
  width:calc(20% - 10px);
  margin:5px;
  box-sizing:border-box;
}
<div class="grid">
<span>a</span>
<span>b</span>
<span>c</span>
<span>d</span>
</div>

<div class="grid">
<span>a</span>
<span>b</span>
</div>

<div class="grid">
<span>a</span>
<span>b</span>
<span>c</span>
<span>d</span>
<span>e</span>
</div>

Another idea with CSS grid where the syntax can be more intuitive and easily scalable for any number of columns:

.grid {
  display:grid;
  grid-template-columns:repeat(var(--n,5),1fr);
  grid-gap:5px;
  margin:5px;
}
.grid > span {
  padding:10px;
  background:yellow;
  
}

.grid > span:nth-last-child(1) { grid-column-end:-1; }
.grid > span:nth-last-child(2) { grid-column-end:-2; }
.grid > span:nth-last-child(3) { grid-column-end:-3; }
.grid > span:nth-last-child(4) { grid-column-end:-4; }
.grid > span:nth-last-child(5) { grid-column-end:-5; }
.grid > span:nth-last-child(6) { grid-column-end:-6; }

/*.grid > span:nth-last-child(n) { grid-column-end:-n; }
  and so on ...
*/
<div class="grid">
<span>a</span>
<span>b</span>
<span>c</span>
</div>
<div class="grid" style="--n:4">
<span>a</span>
<span>b</span>
<span>c</span>
</div>

<div class="grid" style="--n:3">
<span>a</span>
<span>b</span>
</div>

<div class="grid" style="--n:6">
<span>a</span>
<span>b</span>
<span>c</span>
<span>d</span>
<span>e</span>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • im not sure it will be 5 childs. for the time being, im saying "5 column max", but the number of children will vary – oldboy May 11 '19 at 22:40
  • @Anthony yes, I meant column not child .. As you can see, in the example I used different number of child. Also added another example at the end – Temani Afif May 11 '19 at 22:41
  • yeah, so i tried to use `justify-content` on the container, but because the width of the container is determined by the collective width of children, gap, and padding, it doesnt help. i gtg but ill be back later and take a more in depth look at ur answer. one solution that pops into mind after seeing ur approach is to use ur approach and simply set an explicit width of the container, but this might cause issues – oldboy May 11 '19 at 22:43
  • @Anthony check the third method I added, it should be more suitable for your case if the number of columns is no known – Temani Afif May 11 '19 at 22:44
  • ok yeah so ive taken a look at your answer. i used grid instead of flex for a very particular reason that i mentioned in the comment section of my question. the first or last idea are certainly practical. any particular reason why the 3rd is the best? i had never heard of that property before, `grid-column-end`, but im looking it up right now – oldboy May 13 '19 at 06:39
  • man is that legit? you can declare css variables in html like that? like not on the root element? – oldboy May 13 '19 at 06:43
  • @Anthony the last idea is the best one because it's scalable, as you can see the number in the nth-last-child is the same as the column-end so whataver the number of columns is, you don't have to change the CSS (you simply add more declaration) ... and yes you can declare CSS variable inside any element, not only :root because it's a like any CSS property ;) – Temani Afif May 13 '19 at 09:21
  • @TemaniAfif right right. wow thats so cool. did it used to be `:root` only? – oldboy May 13 '19 at 21:16
  • 1
    @Anthony never, In most of the examples you see it within `:root` and it's only a habit (not sure who decided about it ..). I personnaly never used it (or rarely) within `:root` – Temani Afif May 13 '19 at 21:18
  • hey temani, would u mind taking a look at [this other question of mine?](https://stackoverflow.com/q/56139497/7543162) i would appreciate it – oldboy May 15 '19 at 01:00
  • Hey buddy, [check out this weird behaviour on mobile.](https://stackoverflow.com/q/57469813/7543162) Any idea what's going on here? – oldboy Aug 13 '19 at 00:44