Animated Background Stripes Effect 12 exercises

Create Fluid Animations with CSS Variables and Dynamic Utilities

We'll define a CSS variable called --stripes-size and set its default value to 20px:

// Setting default stripe options
":root": {
"--stripes-rgb": "0 0 0",
"--stripes-angle": "-45deg",
"--stripes-opacity": "1",
"--stripes-size": "20px",
// ...

Loading solution


Simon: 0:01 Our size modifier is once again going to update a CSS variable's value. This time, we're going to start by defining the CSS variable. We'll call it --stripes-size, unsurprisingly. For the default value, let's go with 20 pixels.

0:15 If we scroll down in our code, we want to change the backgroundSize here to consume this CSS variable two times, one for each 20 pixel, var --stripes-size. I'll copy that. Space and the same once again. Nothing should change, which means that it's working.

0:35 Now, if I was to change this to 40 pixels, you can see that the size is bigger, but there is a problem. It's jumping because it's only translating by 20 pixels, which is halfway of the repeated pattern, and then jumps back. This stripes-size variable should be used in more than one place. It should also be used here in the translate distance, var --stripes-size.

1:03 Now it's not jumping anymore, but it's revealing some gap here. Can you figure out what other place we need to update it too? I know you did. I know you figured that out. Well done. This is in the width calculation here, where we go 100 percent plus this hard-coded 20 pixel. Hard-coded no more. We want var --stripes-size.

1:25 Now, when I save this, we should have this super-fluid animation effect happening, regardless of the size. If we have 10 pixels, it works, although it's very tiny. If we have 70 pixels, it still works. That's great. Let's go back to 20 pixels.

1:43 Now we're going to implement our matchUtilities generation of the size modifiers, so matchUtilities. Hopefully, this time, if it didn't click before, it clicks. The first thing we'll pass is the name of the classes we want to generate. We want stripes-size.

2:03 We will have a function that receives a value and then returns some CSS or CSS-in-JS that redefines the --stripes-size CSS variable to be that value.

2:18 You can see something interesting. We haven't passed any values yet, but you can see that last one is already working with the arbitrary value. We haven't passed any dynamic list of values to iterate through, but it's already supporting the arbitrary value, just by calling the matchUtilities function, which is really cool.

2:37 Speaking of values, let's pass the values object. We have these values here. Let me paste that and turn that into JavaScript. Now we've defined small, medium, large, and extra large. Check this out. Small, medium, large, extra large, and arbitrary value, crazy large.

2:57 If you wanted to let the user define these values in the theme, you could reach out for a specific namespace in your theme object. Here, instead of passing this object, which I will cut to keep in my clipboard, we could pass theme. Let's call the theme key stripesSize.

3:14 Right now, it doesn't exist, so it's not going to generate any value except our arbitrary value, as you can see. Our whole plugin function here that we call at the start can take a second argument, which is right at the end, a config object.

3:29 We can extend the user's theme directly from there. We could provide these default values via a stripesSize key, where we would pass these values. This would set these default values on the user's theme. They would be able to extend that object or override it as they please.

3:48 Let's take a look back at our whole plugin. We are using addBase, Components, Utilities, matchUtilities, and theme to generate CSS variables and keyframe animation in the base layer, generate our stripes component class, which has a linear gradient stacked with CSS variables.

4:04 We then manually generate a few utilities. For the more heavy lifting side of things, we use matchUtilities to generate on-the-fly dynamic utility classes based on the value object path. We do the same for the size modifiers. That is really, really cool.