4

If I have a grid which auto-flows columns

    display: grid;
    grid-auto-flow: column;

So I don't know the number of columns I have

how would I say "I want all columns to be the minimum size for the contents and the last column to fill all available space"?

I'm aware that in the simple case this is achievable with flexbox, I'm trying to bolster my grid knowledge specifically.

George Mauer
  • 117,483
  • 131
  • 382
  • 612

2 Answers2

2

If it's about the first column, you can easily do it by defining one template (the explicit grid) to 1fr and the implicit grid to min-content

.box {
  display: grid;
  grid-auto-flow: column;
  grid-template-columns:1fr;
  grid-auto-columns:min-content;
  margin:5px;
}

span {
  border: 1px solid;
  padding: 5px;
}
<div class="box">
  <span>aa</span>
  <span>b</span>
  <span>ccc</span>
  <span>d</span>
  <span>eeee</span>
</div>

<div class="box">
  <span>aa</span>
  <span>b</span>
  <span>eeee</span>
</div>

For the last column you may need more hacks where we consider the same configuration but we move all the elements to before the implicit grid to keep the 1fr the last. We need to use negative number combined with a random area to do this. (more details about this trick here)

The only drawback is that you need to define all the grid-column but you don't need to know the number of column, only the max number (you can probably consider SASS to generate the rules)

.box {
  display: grid;
  grid-auto-flow: column;
  grid-template-columns:1fr;
  grid-auto-columns:min-content;
  margin:5px;
}

span {
  border: 1px solid;
  padding: 5px;
}

span:nth-last-child(2) { grid-column:random -1; }
span:nth-last-child(3) { grid-column:random -2; }
span:nth-last-child(4) { grid-column:random -3; }
span:nth-last-child(5) { grid-column:random -4; }
span:nth-last-child(6) { grid-column:random -5; }
span:nth-last-child(7) { grid-column:random -6; }
span:nth-last-child(8) { grid-column:random -7; }
span:nth-last-child(9) { grid-column:random -8; }
/* and so on
span:nth-last-child(n) { grid-column:random -(n-1); }
*/
<div class="box">
  <span>aa</span>
  <span>b</span>
  <span>ccc</span>
  <span>d</span>
  <span>eeee</span>
</div>

<div class="box">
  <span>aa</span>
  <span>b</span>
  <span>eeee</span>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • Hmm but even the hacks option would require the css knowing about the number of columns, wouldn't it? I guess you can upper bound it – George Mauer Oct 20 '19 at 19:59
  • 1
    @GeorgeMauer yes it requires only the max number of column if possible, not the exact number ... I am thinking about another alternative ;) – Temani Afif Oct 20 '19 at 20:00
  • @GeorgeMauer I guess this is the best you will get from me actually, let's wait for more users to come. Worth to note that CSS grid isn't designed for such use case so the answers will most likely be workarounds or hacks. – Temani Afif Oct 20 '19 at 20:30
  • spanning a hudge amount with the last-child could also be one of those tricks `span:last-child { grid-column: span 100; }` https://codepen.io/gc-nomade/pen/rNNWQaE ? – G-Cyrillus Oct 20 '19 at 20:51
  • @G-Cyr yes, not sure why It didn't work when I tried it but it seems to be fine. I was probably having a style interferring. I guess it worth posting as answer ;) – Temani Afif Oct 20 '19 at 20:56
  • take it as yours, i dropped the min-content and the grid-template-column parts ;) – G-Cyrillus Oct 20 '19 at 20:58
  • @G-Cyr I guess I have tried a very big number and got a random behavior at the end upon resize: https://jsfiddle.net/sxdvceLu/ .. 1000 was too much – Temani Afif Oct 20 '19 at 20:58
  • yep , it breaks at one time ;) and i guess with chrome ;) – G-Cyrillus Oct 20 '19 at 20:59
  • @G-Cyr yes it's chrome. Anyway, it still deserves to be an answer. With a good number we won't notice anything and it won't be funny to have all the hacks in one answer :) – Temani Afif Oct 20 '19 at 21:06
2

Another unexpected way could be to set a hudge amount of column spanning on the last element and using only grid-auto-columns: auto leaving the grid-template-columns aside .

.box {
  display: grid;
  grid-auto-flow: column;
  /* grid-auto-columns: auto; useless here */
  margin: 5px;
}

span {
  border: 1px solid;
  padding: 5px;
  margin: 1px
}

span:last-child {
  grid-column: span 100;
  background: tomato
}
<div class="box">
  <span>aa</span>
  <span>b</span>
  <span>ccc</span>
  <span>d</span>
  <span>eeee</span>
</div>

<div class="box">
  <span>aa</span>
  <span>b</span>
  <span>eeee</span>
</div>
<div class="box">
  <span>aa</span>
  <span>b</span>
  <span>aa</span>
  <span>b</span>
  <span>aa</span>
  <span>b</span>
  <span>aa</span>
  <span>b</span>
  <span>aa</span>
  <span>b</span>
  <span>aa</span>
  <span>b</span>
  <span>aa</span>
  <span>b</span>
  <span>aa</span>
  <span>b</span>
  <span>aa</span>
  <span>b</span>
  <span>aa</span>
  <span>b</span>
  <span>aa</span>
  <span>b</span>
  <span>aa</span>
  <span>b</span>
  <span>aa</span>
  <span>b</span>
  <span>aa</span>
  <span>b</span>
  <span>aa</span>
  <span>b</span>
  <span>aa</span>
  <span>b</span>
  <span>aa</span>
  <span>b</span>
  <span>aa</span>
  <span>b</span>
  <span>aa</span>
  <span>b</span>
  <span>aa</span>
  <span>b</span>
  <span>aa</span>
  <span>b</span>
  <span>aa</span>
  <span>b</span>
  <span>break me with so many</span>
  <span>b</span>
  <span>aa</span>
  <span>b</span>
  <span>aa</span>
  <span>b</span>
  <span>eeee</span>
</div>

not so sure that it reflects your reality though.

Another alternative very similar:

span {
  border: solid;
  padding: 1em;
  margin: 1px;
  min-width: min-content;
}
.box {
  display: grid;
  grid-auto-flow: column;
}
span:last-child,b {
  color: tomato;
  grid-column: span 70;
  width: auto;
}
<div class="box">
  <span>aa</span>  <span>bbbbb bbbbbbbb bbbbbbbb bbbbbbbb bbbbbbb bbbbbbbb bbbbbbbbb</span>
  <span><b>To be tested in fullpage mode too.</b></span>
  <span>desd</span>
  <span>/</span>  
</div>

and let's do another one without spanning, but involving a pseudo on the last child

span {
  border: solid;
  padding: 1em;
  margin: 1px;
}

.box {
  display: grid;
  grid-auto-flow: column;
}

span:last-child {
  color: tomato;
  /* trick start */
  overflow: hidden;
}

span:last-child:after {
  content: "";
  display: block;
  width: 100vw;
}
/* trick end */
<div class="box">
  <span>aa</span> <span>bbbbb bbbbbbbb bbbbbbbb bbbbbbbb bbbbbbb bbbbbbbb bbbbbbbbb</span>
  <span>cccc ccc ccccccc ccc cccccc cccccccccc</span>
  <span>desd</span>
  <span>last child</span>
</div>
G-Cyrillus
  • 101,410
  • 14
  • 105
  • 129
  • `grid-auto-columns` can be ommited by the way since the default value is already `auto` – Temani Afif Oct 20 '19 at 21:21
  • @TemaniAfif yep i did into the second snippet while looking for a bit more flexibility with the columns, even then not sure it is what the op hopes :) – G-Cyrillus Oct 20 '19 at 21:35