{"id":1920581,"date":"2023-01-25T11:05:04","date_gmt":"2023-01-25T16:05:04","guid":{"rendered":"https:\/\/wordpress-1016567-4521551.cloudwaysapps.com\/plato-data\/animating-css-grid-how-to-examples\/"},"modified":"2023-01-25T11:05:04","modified_gmt":"2023-01-25T16:05:04","slug":"animating-css-grid-how-to-examples","status":"publish","type":"station","link":"https:\/\/platodata.io\/plato-data\/animating-css-grid-how-to-examples\/","title":{"rendered":"Animating CSS Grid (How To + Examples)"},"content":{"rendered":"
<\/div>\n

I\u2019m pleased to shine a light on the fact that the CSS grid-template-rows<\/code><\/a> and grid-template-columns<\/code><\/a> properties are now animatable in all major web browsers<\/a>! Well, CSS Grid has technically supported animations for a long time, as it\u2019s baked right into the CSS Grid Layout Module Level 1 spec<\/a>.<\/p>\n

But animating these grid properties only recently gained supported by all three major browsers. Shall we take a look at a few examples to get the creative juices flowing?<\/p>\n

<\/span> <\/p>\n

\n
\n

<\/a>Table of contents<\/h3>\n<\/p><\/div>\n<\/div>\n

<\/a>Example 1: Expanding sidebar<\/h3>\n

First of all, this is what we\u2019re talking about:<\/p>\n

A simple two-column grid. Now, before, you might not<\/em> have built this using CSS Grid because animations and transitions weren\u2019t supported, but what if you wanted the left column \u2014 perhaps a sidebar navigation \u2014 to expand on hover? Well, now that\u2019s possible.<\/p>\n

I know what you\u2019re thinking: \u201cAnimating a CSS property? Easy peasy, I\u2019ve been doing it for years!\u201d<\/em> Me too. However, I ran into an interesting snag while experimenting with a particular use case.<\/p>\n

So, we want to transition the grid itself (specifically grid-template-columns<\/code>, which is set on the .grid<\/code> class in the example). But the left column (.left<\/code>) is the selector that requires the :hover<\/code> pseudo-class. While JavaScript can solve this conundrum easily \u2014 thanks, but no thanks \u2014 we can accomplish it with CSS alone.<\/p>\n

Let\u2019s walk through the whole thing, starting with the HTML. Pretty standard stuff really\u2026 a grid with two columns.<\/p>\n

<div class=\"grid\"> <div class=\"left\"><\/div> <div class=\"right\"><\/div>\n<\/div><\/code><\/pre>\n

Putting the cosmetic CSS aside, you\u2019ll first need to set display: grid<\/code> on the parent container (.grid<\/code>).<\/p>\n

.grid { display: grid;\n}<\/code><\/pre>\n

Next, we can define and size the two columns using the grid-template-columns<\/code> property. We\u2019ll make the left column super narrow, and later increase its width on hover. The right column takes up the rest of the remaining space, thanks to the auto<\/code> keyword.<\/p>\n

.grid { display: grid; grid-template-columns: 48px auto;\n}<\/code><\/pre>\n

We know we\u2019re going to animate this thing, so let\u2019s go ahead and throw a transition<\/code> in there while we\u2019re at it so the change between states is smooth and noticeable.<\/p>\n

.grid { display: grid; grid-template-columns: 48px auto; transition: 300ms; \/* Change as needed *\/\n}<\/code><\/pre>\n

That\u2019s it for the .grid<\/code>! All that\u2019s left is to apply the hover state. Specifically, we\u2019re going to override the grid-template-columns<\/code> property so that the left column takes up a greater amount of space on hover.<\/p>\n

This alone isn\u2019t all that interesting, although it\u2019s awesome that animations and transitions are supported now in CSS Grid. What\u2019s more interesting is that we can use the relatively new :has()<\/code><\/a> pseudo-class<\/a> to style the parent container (.grid<\/code>) while the child (.left<\/code>) is hovered.<\/p>\n

.grid:has(.left:hover) { \/* Hover styles *\/\n}<\/code><\/pre>\n

In plain English this is saying, \u201cDo something to the .grid<\/code> container if it contains an element named .left<\/code> inside of it that is in a hover state.\u201d<\/em> That\u2019s why :has()<\/code> is often referred to as a \u201cparent\u201d selector. We can finally select a parent based on the children it contains \u2014 no JavaScript required!<\/p>\n

So, let\u2019s increase the width of the .left<\/code> column to 30%<\/code> when it is hovered. The .right<\/code> column will continue to take up all the leftover space:<\/p>\n

.grid { display: grid; transition: 300ms; grid-template-columns: 48px auto;\n} .grid:has(.left:hover) { grid-template-columns: 30% auto;\n}<\/code><\/pre>\n

We could use CSS variables as well, which may or may not look cleaner depending on your personal preferences (or you might be using CSS variables in your project anyway):<\/p>\n

.grid { display: grid; transition: 300ms; grid-template-columns: var(--left, 48px) auto;\n} .grid:has(.left:hover) { --left: 30%;\n}<\/code><\/pre>\n

I love<\/em> that CSS grids can be animated now, but the fact that we can build this particular example with just nine lines of CSS is even more astounding.<\/p>\n

Here\u2019s another example by Olivia Ng<\/a> \u2014 similar concept, but with content (click on the nav icon):<\/p>\n

<\/a>Example 2: Expanding Panels<\/h3>\n

This example transitions the grid container (the column widths) but also the individual columns (their background colors). It\u2019s ideal for providing more content on hover.<\/p>\n

It\u2019s worth remembering that the repeat()<\/code> function sometimes produces buggy transitions, which is why I set the width of each column individually (i.e. grid-template-columns: 1fr 1fr 1fr<\/code>).<\/p>\n

<\/a>Example 3: Adding Rows and Columns<\/h3>\n

This example animatedly \u201cadds\u201d a column to the grid. However \u2014 you guessed it \u2014 this scenario has a pitfall too. The requirement is that the \u201cnew\u201d column mustn\u2019t be hidden (i.e. set to display: none<\/code>), and CSS Grid must acknowledge its existence while setting its width to 0fr<\/code>.<\/p>\n

So, for a three-column grid \u2014 grid-template-columns: 1fr 1fr 0fr<\/code> (yes, the unit must be declared even though the value is 0<\/code>!) transitions into grid-template-columns: 1fr 1fr 1fr<\/code> correctly, but grid-template-columns: 1fr 1fr<\/code> doesn\u2019t. In hindsight, this actually makes perfect sense considering what we know about how transitions work<\/a>.<\/p>\n

Here\u2019s another example by Michelle Barker<\/a> \u2014 same concept, but with an extra column and lot<\/em> more pizzazz. Make sure to run this one in full-screen mode because it\u2019s actually responsive (no trickery, just good design!).<\/p>\n

<\/a>A few more examples<\/h3>\n

Because why not?<\/p>\n

This \u201cAnimated Mondrian\u201d is the original proof of concept for animated CSS grids by Chrome DevRel<\/a>. The grid-row<\/code>\u2018s and grid-column<\/code>\u2018s utilize the span<\/code> keyword to create the layout you see before you, and then the grid-template-row<\/code>\u2019s and grid-template-column<\/code>\u2018s are animated using a CSS animation. It\u2019s nowhere near as complex as it looks!<\/p>\n

Same concept, but with more of that Michelle Barker pizzazz. Could make a nice loading spinner?<\/p>\n

Wrapping up with a bit of nostalgia (showing my age here), the not-very-griddy animated CSS grid by Andrew Harvard<\/a>. Again \u2014 same concept \u2014 it\u2019s just that you can\u2019t see the other grid items. But don\u2019t worry, they\u2019re there.<\/p>\n