Considering your three requirements:
- A grid with a variable number of rows.
- Every row should have a variable size (auto will do).
- The last row should always take up all the remaining space.
Flexbox is well-suited for the job. In fact, it may be the perfect fit (depending on your other requirements). I've provided a code sample below.
But if Grid Layout is what you want, then I think you're going to be disappointed. I don't believe Level 1 can do the job.
The closest you can get would be:
grid-template-rows: repeat(auto-fit, minmax(auto, 1px)) 1fr;
But it won't work because the current grid spec doesn't support this syntax.
repeat(auto-fit, auto) 1fr
This is the code you tried. It's not valid because auto
and fr
cannot be used with auto-fit
.
7.2.2.1. Syntax of
repeat()
Automatic repetitions (auto-fill
or auto-fit
) cannot be combined
with intrinsic or flexible sizes.
An intrinsic sizing function is min-content
, max-content
, auto
, fit-content()
.
A flexible sizing function is <flex>
(fr
).
You can get around the auto
limitation with something like this:
repeat(auto-fit, minmax(auto, 1px)) 1fr
minmax(min,max)
Defines a size range greater than or equal to min and less than or
equal to max.
If max < min, then max is ignored and minmax(min,max)
is treated as min.
As a maximum, a <flex>
value sets the track’s flex factor; it is invalid as a minimum.
That works to properly auto-size your rows, whether the container has the default auto
height or a height
/ min-height
defined. demo
But it still doesn't solve the last row problem, since the 1fr
remains invalid, and causes the entire rule to fail. demo
Something like this would be valid:
repeat(auto-fit, minmax(auto, 1px)) 10em
But the auto-fit
doesn't work as you expect: the 10em
is applied to the second row. demo
And the rule doesn't work as expected if the container has a height
or min-height
defined. demo
Even with CSS Grid Layout now widely available, Flexbox is still the better choice in some cases.
This covers all your requirements with clean and simple code:
article {
display: flex;
flex-direction: column;
height: 100vh;
}
section:last-child {
flex-grow: 1;
}
section {
/* flex-basis: auto <-- this is a default setting */
margin-bottom: 10px;
background-color: lightgreen;
}
body {
margin: 0;
}
<article>
<section>text text text</section>
<section>text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text
text text text text text text text text text text </section>
<section>text text text text text text text text text text text text text text text text text text text text text text text text text text text</section>
<section>text text text text text text text text text text text text text text text text text text text text text text text text text text text</section>
<section>text text text text text text text text text text text text text text text text text text text text text text text text text text text</section>
</article>