CSS - Grid

CSS Grid Layout excels at dividing a page into major regions or defining the relationship in terms of size, position, and layer, between parts of a control built from HTML primitives.

Like tables, grid layout enables an author to align elements into columns and rows. However, many more layouts are either possible or easier with CSS grid than they were with tables. For example, a grid container’s child elements could position themselves so they actually overlap and layer, similar to CSS positioned elements.

CSS Grid Layout on the Mozilla Developer Network

Hello subgrid!

We have had Grid Layout in browsers for two years. Long enough for us to start to find the edges, and discover things we really wish it could do. The biggest missing feature from Level 1 was subgrid, which has become the main feature for Level 2 of the specification. In this talk I’ll introduce subgrid, with use cases, example code and some thoughts on where we might see Grid going in the future.

[…]

Resources

The following resources were mentioned during the presentation or are useful additional information.

Slides and code examples can be found in the source link.

Equal height rows in CSS Grid Layout

Great answer by Michael_B on Stack Overflow:

Short Answer

If the goal is to create a grid with equal height rows, where the tallest cell in the grid sets the height for all rows, here’s a quick and simple solution:

  • Set the container to grid-auto-rows: 1fr

How it works

Grid Layout provides a unit for establishing flexible lengths in a grid container. This is the fr unit. It is designed to distribute free space in the container and is somewhat analogous to the flex-grow property in flexbox.

If you set all rows in a grid container to 1fr, let’s say like this:

grid-auto-rows: 1fr;

… then all rows will be equal height.

It doesn’t really make sense off-the-bat because fr is supposed to distribute free space. And if several rows have content with different heights, then when the space is distributed, some rows would be proportionally smaller and taller.

Except, buried deep in the grid spec is this little nugget:

7.2.3. Flexible Lengths: the fr unit

When the available space is infinite (which happens when the grid container’s width or height is indefinite), flex-sized (fr) grid tracks are sized to their contents while retaining their respective proportions.

The used size of each flex-sized grid track is computed by determining the max-content size of each flex-sized grid track and dividing that size by the respective flex factor to determine a “hypothetical 1fr size”.

The maximum of those is used as the resolved 1fr length (the flex fraction), which is then multiplied by each grid track’s flex factor to determine its final size.

So, if I’m reading this correctly, when dealing with a dynamically-sized grid (e.g., the height is indefinite), grid tracks (rows, in this case) are sized to their contents.

The height of each row is determined by the tallest (max-content) grid item.

The maximum height of those rows becomes the length of 1fr.

That’s how 1fr creates equal height rows in a grid container.


Why flexbox isn’t an option

As noted in the question, equal height rows are not possible with flexbox.

Flex items can be equal height on the same row, but not across multiple rows.

This behavior is defined in the flexbox spec:

6. Flex Lines

In a multi-line flex container, the cross size of each line is the minimum size necessary to contain the flex items on the line.

In other words, when there are multiple lines in a row-based flex container, the height of each line (the “cross size”) is the minimum height necessary to contain the flex items on the line.

Breaking Out with CSS Grid Layout

A side-by-side comparison of a narrow viewport and a wider one, with one grid item spanning the full width in the latter, while the rest are constrained via the centre column.

If you’ve ever needed to have a content column with a maximum width, but have specific elements span the full width of the viewport, thus breaking out of the column, CSS Grid can do this really simply. First the grid on the container:

Code language: CSS

.content {
  display: grid;
  grid-template-columns: 
    [full-start] minmax(1em, 1fr) 
    [main-start] minmax(0, 40em) [main-end]
    minmax(1em, 1fr) [full-end];
}

This defines the columns, including the max width of the content, and a gutter. For normal content:

Code language: CSS

.content > * {
  grid-column: main;
}

Then for items to span the full viewport:

Code language: CSS

.content__full {
  grid-column: full;
}

See the source link for more details.

Auto-Sizing Columns in CSS Grid: `auto-fill` vs `auto-fit`

auto-fill FILLS the row with as many columns as it can fit. So it creates implicit columns whenever a new column can fit, because it’s trying to FILL the row with as many columns as it can. The newly added columns can and may be empty, but they will still occupy a designated space in the row.

auto-fit FITS the CURRENTLY AVAILABLE columns into the space by expanding them so that they take up any available space. The browser does that after FILLING that extra space with extra columns (as with auto-fill ) and then collapsing the empty ones.

Tags

The Story of CSS Grid, from Its Creators

On October 17th, Microsoft’s Edge browser shipped its implementation of CSS Grid. This is a milestone for a number of reasons. First, it means that all major browsers now support this incredible layout tool. Second, it means that all major browsers rolled out their implementations in a single year(!), a terrific example of standards success and cross-browser collaboration. But third, and perhaps most interestingly, it closes the loop on a process that has been more than 20 years in the making.

[…]

“I don’t recall a feature ever shipping like CSS Grid has shipped. Every major browser will have shipped it within a matter of a single year, and it will be interoperable because we’ve been… implementing [it] behind flags, testing it, making future changes behind flags, and then when it was deemed stable, all the browsers are now shipping it natively.”

“With everybody shipping at approximately the same time,” Atkins said, “[Grid] goes from an interesting idea you can play with to something that you just use as your only layout method without having to worry about fallbacks incredibly quickly. … [It’s been] faster than I expected any of this to work out.”

[…]

“It is the most powerful layout tool that we have invented yet for CSS,” [Tab] Atkins said. “It makes page layouts so ridiculously easy. … [P]eople have always been asking for better layouts. Just for author-ability reasons and because the hacks that we were employing weren’t as powerful as the old methods of just put[ting] it all in a big old table element—that was popular for a reason; it let you do powerful complex layouts. It was just the worst thing to maintain and the worst thing for semantics. And Grid gives you back that power and a lot more, which is kind of amazing.”

Should I try to use the IE implementation of CSS Grid Layout?

If you are using Grid in a very simple way, and positioning items rather than using auto-placement then the fact that grid exists in Internet Explorer from version 10 could turn out very useful. You could certainly use this in order to create a simpler layout for IE10 and up, once Grid is shipped in other browsers.

However be aware that this is going to require some additional testing and work, you are unlikely to be able to simply rely on Autoprefixer to run and do the work for you. For example, if you have used auto placement for any item and then don’t set a position using the -ms properties, that item is going to stack up with any other unpositioned items in the first grid cell.

The good news is that the IE implementation is pretty much frozen in time between IE10, 11 and current versions of Edge (presumably until Edge updates to the new specification). So work you do to implement grid in IE should work in those versions without needing to do different things for different IEs.

Excluding Microsoft Edge's old CSS Grid implementation with feature queries

The challenge is Microsoft Edge, the only modern browser that, as of this writing, still uses the old grid specification. It returns true for @supports (display: grid) {}, even though its grid support is spotty and non-standard. Most relevant for our example is the lack of support for the grid-template-areas and grid-area properties and for the minmax() function. As a result, a feature query targeting display: grid would not exclude Microsoft Edge, and users of this browser would be served a broken layout. To resolve this issue and serve up grid layouts to Microsoft Edge only when the browser gets full support for the specification, target one of the unsupported features instead:

Code language: CSS

@supports (grid-area: auto) {}