How Is "Grid-Template-Rows: Auto Auto 1Fr Auto" Interpreted

How is grid-template-rows: auto auto 1fr auto interpreted?

With CSS grid layout, the grid-template-rows value auto means:

The size of the rows is determined by the size of the container, and on the size of the content of the items in the row

and 1fr is a new flexible unit in GRID css. [Fr] is a fractional unit and 1fr is for 1 part of the available space.

so thats why your 3rd grid item is taking the remaining space and all remaining grid items are taking space according to its content

CSS Grid with variable number of auto rows, but one row should take 1fr

Considering your three requirements:

  1. A grid with a variable number of rows.
  2. Every row should have a variable size (auto will do).
  3. 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>

unexpected behavior with grid-template-rows and 1fr on chrome

The grid container is interpreting the min-height: 100vh on the flex parent differently in Chrome and Firefox.

As you noted, in Firefox everything works as you expect. But in Chrome, the min-height is effectively ignored (even though flex-grow: 1 works on the same element).

If you switch to height: 100vh you'll see the 1fr work in Chrome, as well.

I would have to research more to tell you if this is a bug or not.

Consider nesting the grid inside another grid, as opposed to flex, container.

.container {
display: grid;
min-height: 100vh;
grid-template-rows: min-content 1fr;
}

.grid {
background-color: red;
padding: 1rem;
grid-gap: 1rem;
display: grid;
grid-template-rows: 1fr auto;
}

.grid>* {
background-color: white;
}
<div class="container">
<h1>some title</h1>
<div class="grid">
<div>line 1</div>
<div>line 2</div>
</div>
</div>

what is auto-fit in grid-tempelate-columns?

repeat() => is used in grid-template-columns and grid-template-rows. It repeats the fragment according to your screen size.

auto-fit => it will fit as many columns on your screens according to your screen size.

minmax() => this function will choose a size range greater than or equal to min and less than or equal to max.which means between 300px and 1fr(fr = fractional unit default size of a column).

this line of css will create responsive columns according to your screen size and adjust the number of columns as the screen size increases or decreases

Why grid-template-rows track pattern does not repeat like grid-template-columns

A CSS grid layout by default fills all the explicit rows (note that explicit rows or columns are that which you specify using properties like grid-template-columns, grid-template-rows, grid-template-areas) and creates new rows as necessary (implicit rows). This behavior is due to grid-auto-flow property - see the below excerpt from MDN:

grid-auto-flow: row

Is a keyword specifying that the auto-placement algorithm places
items, by filling each row in turn, adding new rows as necessary. If
neither row nor column is provided, row is assumed.


Auto-flow in row direction

This explains why the grid items fills all the explicit columns in a row and then moves on to the next row creating an implicit row if needed. You can specify the size of implicit rows (from the 4th row in your example) using grid-auto-rows property:

* {  box-sizing: border-box;}
.grid { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-template-rows: 300px 1fr 100px; grid-gap: 20px; grid-auto-rows: 50px; /* size implicit rows */}
.grid_item { border: 1px solid rgb(0, 95, 197); border-radius: 3px; background-color: rgba(0, 95, 107, 0.8); padding: 0.2em; margin: 0; /* reset h1 margin to see grid better */ overflow: hidden; /* hide overflow text */}
<body>  <div class="grid">    <h1 class="grid_item">300 px row, 1fr column</h1>    <h1 class="grid_item">300 px row, 1fr column</h1>    <h1 class="grid_item">300 px row, 1fr column</h1>    <h1 class="grid_item">1fr row, 1fr column</h1>    <h1 class="grid_item">1fr row, 1fr column</h1>    <h1 class="grid_item">1fr row, 1fr column</h1>    <h1 class="grid_item">100 px row, 1fr column </h1>    <h1 class="grid_item">100 px row, 1fr column </h1>    <h1 class="grid_item">100 px row , 1fr column</h1>    <h1 class="grid_item">1fr row, 1fr column</h1>    <h1 class="grid_item">1fr row, 1fr column</h1>    <h1 class="grid_item">1fr row, 1fr column</h1>    <h1 class="grid_item">1fr row, 1fr column</h1>    <h1 class="grid_item">1fr row, 1fr column</h1>    <h1 class="grid_item">1fr row, 1fr column</h1>    <h1 class="grid_item">1fr row, 1fr column</h1>    <h1 class="grid_item">1fr row, 1fr column</h1>    <h1 class="grid_item">1fr row, 1fr column</h1>    <h1 class="grid_item">1fr row, 1fr column</h1>    <h1 class="grid_item">1fr row, 1fr column</h1>  </div></body>


Related Topics



Leave a reply



Submit