Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mixing fixed length and repeat() in CSS Grid

Tags:

html

css

css-grid

I'm trying to make a calendar using a grid layout. Each day of the week will have a header. My goal is to set the height of the header (ie: the first row in the grid) to 30px, and have the rest of the rows split the rest of the available space.

My calendar CSS looks like this:

.calendar{
    display:grid;
    grid-template-columns:repeat(1,1fr);
    grid-template-rows:30px repeat(auto-fill,1fr);
}

Now, I thought that would do exactly what I want, but that 30px has no effect, and each row is an equal height. Is it possible to mix a static value and repeat()?

I realize I can just make 2 grids - one for the headers and one for the days - but I'm curious if there's a way cleaner way.

Demo here: https://codepen.io/anon/pen/yGEaOm

.calendar {
  display: grid;
  grid-template-columns: repeat(1, 1fr);
  grid-template-rows: 30px repeat(auto-fill, 1fr);
}


/** Appearance styles that don't affect the layout */
.calendar {
  min-height: 200px;
}
.day {
  border: 1px solid black;
  display: flex;
  align-items: center;
  justify-content: center;
}
<div class="calendar">
  <div class="day">
    First
  </div>
  <div class="day">
    Second
  </div>
</div>
like image 700
Quasipickle Avatar asked Jan 08 '19 00:01

Quasipickle


People also ask

Can you use repeat in grid template areas?

You can also use the shorthand repeat code like above to make the columns repeat. For example, “grid-template-columns:repeat (9, 1fr);” shows the combined commands that specify the fraction code and the number of columns.

What does 1fr mean in the following code grid-template-columns 150px 150px 1fr 1fr?

What does 1fr mean in the following code? grid-template-columns: 150px 150px 1fr 1fr; The first two columns will be two fraction units of the stated width. The third and fourth columns is 1 fraction unit of the remaining space in the grid.

What is 1fr and 2FR in CSS?

So each 1FR=1/5th of the available space or 20%. So, 2FR is 2/5th or 40% wide. Now you have 4 columns but a total of 5FRs so automatically each fraction takes up 20% of the available space. So, the first column takes up 2 fractions of the space, that's 40%.


1 Answers

Short Answer

Instead of:

grid-template-rows: 30px repeat(auto-fill, 1fr)

Try this:

grid-template-rows: 30px repeat(auto-fit, minmax(10px, 1fr))

.calendar {
  display: grid;
  grid-template-columns: repeat(1, 1fr);
  grid-template-rows: 30px repeat(auto-fit, minmax(10px, 1fr));
  grid-row-gap: 2px;
}

/** Appearance styles that don't affect the layout */
.calendar {
  min-height: 200px;
  padding: 2px;
  border: 1px solid red;
}
.day {
  border: 1px dashed black;
  display: flex;
  align-items: center;
  justify-content: center;
}
<div class="calendar">
  <div class="day">First</div>
  <div class="day">Second</div>
</div>

Explanation

Note this rule in your code:

grid-template-rows: 30px repeat(auto-fill, 1fr)

This rule is invalid.

enter image description here

It is, therefore, ignored by the browser and grid-template-rows falls back to its default setting: none (which means all rows will be implicitly created and sized by grid-auto-rows, who's default value is auto).

From the spec:

§ 7.2. Explicit Track Sizing: the grid-template-rows and grid-template-columns properties

The none value.

Indicates that no explicit grid tracks are created by this property (though explicit grid tracks could still be created by grid-template-areas).

Note: In the absence of an explicit grid any rows/columns will be implicitly generated, and their size will be determined by the grid-auto-rows and grid-auto-columns properties.

The main problem is that auto-fill (and auto-fit) cannot be combined with intrinsic or flexible lengths, such as auto, min-content or fr.

§ 7.2.2.1. Syntax of repeat()

  • Automatic repetitions (auto-fill or auto-fit) cannot be combined with intrinsic or flexible sizes.

§ 11. Grid Sizing

  • An intrinsic sizing function is min-content, max-content, auto and fit-content()).

  • A flexible sizing function is a dimension with the fr unit.

Therefore, because your rule ((auto-fill, 1fr)) contains auto-fill with a flexible sizing function (fr), it cannot work.

A solution may be to work around the problem with minmax().

Instead of:

grid-template-rows: 30px repeat(auto-fill, 1fr)

Try this:

grid-template-rows: 30px repeat(auto-fill, minmax(10px, 1fr))

More details:

  • What is the difference between auto-fill and auto-fit?
  • minmax fails (invalid property value)
  • Why auto-fit or auto-fill not working properly with minmax?
like image 168
Michael Benjamin Avatar answered Oct 10 '22 01:10

Michael Benjamin