Check out a free preview of the full Dynamic CSS with Custom Properties (aka CSS Variables) course

The "Fallbacks" Lesson is part of the full, Dynamic CSS with Custom Properties (aka CSS Variables) course featured in this preview video. Here's what you'd learn in this lesson:

Lea demonstrates using fallbacks to avoid having to override properties with a selector of the same specificity, briefly demonstrates using @property instead of a fallback, and how to select the fallback value. What happens when there is no support for CSS variables, using @supports to provide more elaborate fallback styling, and how to detect @property using JavaScript are also covered in this segment.


Transcript from the "Fallbacks" Lesson

>> So what do I mean by fallbacks. Fallbacks have multiple interpretations. Here we have a gallery of values cut pictures and we have a little bit of code here that uses custom properties to apply transforms individually, namely scale and rotate transforms. So we want to apply subtle rotations to some of these pictures.

So let's do save and child odd to apply a rotation to every other picture. And now you see this is not working. I'm not surprised that it's not working, this is the whole point. I'm going to explain why it's not working. But at this point we might have been quite puzzled by this, but let's continue writing the code as we intended.

So we also wanted to apply a different rotation on every third image. So let's do something like this, still not working. And we wanted to also scale images when they are hoovered. So we're gonna add a hover style as well that scales them by 20%. And notice what's happening here.

The transforms are either applied together or not at all. Either we get no rotation or we get both rotation and scale. And why is that? This is because here where we're using our scale and rotate custom properties, the browser doesn't know what value to apply when they are not both set.

So, this style only works when we set both of them, which is not very useful. The whole point is that we can use custom properties to independently set parts of style. However, the bar function provides a second argument that we can use to provide such fallbacks. So we would provide the fallback of one for the scale transform so that no scale happens if we haven't set this property.

And zero degrees for the rotate transport and now it's suddenly all works, now we get the the rotations that we wanted and we also get the entirely independent scale that we wanted. You might be thinking, why don't I just do this? Why don't I just go here and set scale and rotate here?

And then they always have a value. As you'll see, this also works. You could do that. It's not as good because the problem in that case is that anyone else, who wants to style this gallery, and wants to override these properties, needs to use a selector of at least the same specificity as the one you've used.

Whereas with fallbacks, any code that sets these properties no matter how, even if they're inherited, or if they're set through a very low specificity selector, it just works. And lastly, another alternative to making our code work is to just register these properties, we could use @property. Let's register a scale for example.

And we can say the syntax is a number. It does not inherit. It wouldn't make sense to make it inherit. And its initial value is 1. And now we don't actually need to provide the fallback. And that is actually a far superior method because it means that if you're using the custom property multiple times, you don't need to repeat the fallback every time or assign it to a variable or anything like that.

So this is strictly superior but since it's not yet supported everywhere, we need the other workarounds as well. And note that you can't do both. Once you register the property the fallback never applies. In any case that the fallback would apply, you just get the initial value that you have already declared.

So how do these fallbacks actually work? People sort of intuitively understand that when the variable doesn't have a value, they get the fallback. But that is a little bit hand-wavy, what does it mean that the variable doesn't have a value? Let's look at a few examples. So what happens given that we have this code, it sets the background to red, and then it sets the background to whatever X and code is with a fallback of orange.

What happens if accent color is set to an actual color that is supported, like yellowgreen? What would you expect to happen? It's not a trick question. You will get yellowgreen. I mean that's the whole point. What happens when no accent color variable is set anywhere? You would get orange.

That's the whole point. What happens if accent color is set but it's set to the initial keyword? So the initial keyword returns the variable to its initial value, which is exactly the same value as when it's not set. So you would still get the fallback, you would still get orange.

And that is actually, as we'll see later on, this is actually a way to explicitly request the fallback. In some cases we want to do that, we want to trigger the fallback, so we set the variable to initial to do that. And what happens if the browser doesn't support CSS variables at all.

Which these days is basically just IE 11 So many people think, that you would get the fallback in that case. Many people think that, that's the point of using a fallback, but that actually doesn't make sense. How can a browser that doesn't understand CSS variables understand the var function?

A browser that does not support CSS variables, doesn't understand the second line at all. So you would get red. So to sum up, the var fallback is applied when there is no value or when the variable results to initial. And these are not even the only cases. Later on we'll see some other cases that trigger the fallback, but these are the main cases.

And that the var fallback has no help in browsers that don't support CSS variables at all, which like we've said is on the IE 11 really. So this is the browser support right now for CSS variables. I can open it and kind of use if you wanna get more detailed information.

It's basically 95% of visitors. So I imagine for most of you CSS variables are fine to use unless you're working on enterprise, and you still have to support IE 11 at least in a basic way. So what can you do in that case? Well, there's always @supports, do note that IE 11 doesn't support @support either.

So you would only need to use @support to progressively enhance and to use CSS variables inside the @supports rule. There is also the knot version of @supports where you can apply what's inside only when the browser doesn't support something we do not want that. Cuz that only applies your code at the intersection of browsers that don't support the feature and also support @supports, so that's no use here.

But for CSS variables this works fine, you can use any custom property and any value inside here, it could really be anything, like whatever, yolo, anything works fine. Do note that in most cases, you don't actually need to do this. This is for rather elaborate fallbacks where you don't only need to provide an alternative value of the same property, but you also need to style other properties differently.

In this case for example where we just wanna set a different background, We can just use an actual variable. So, to sum up you can use @supports to provide more elaborate fallback styling and do not use negative queries, not for this at least. And this is currently the browser support for @supports.

As you can see it's basically supported everywhere except I11. So a question that some of you might have is, can we use @support to detect @property support? Let's try to do that. Let's take a pause and think how would you try to use @supports to detect @property support.

So my first thought was that I could use and @property rule to the define something, let's say p or foo whatever number and I would give it a syntax of number. And in here its value of, it doesn't really matter. And an initial value just because it's required.

And then I would go here and say, supports, like something, css, variables. I tend to use this query for variables in general. So we wanna apply this to a browser that supports CSS variables in general and doesn't @property. So you would say something like and not, And I would use my registered number, custom property and set it to something that is not a number like foo.

And if this turned out to be unsupported, then this means that the registration worked. But notice that this is not applying, my background is now red, because the browser supports this just fine. The browser will accept any value for any custom property, whether it's registered or not. This is because @supports actually checks syntax that is valid on parse time and any syntax goes at parse time.

The syntax of a registered property is check that computed value time not when the browser is actually reading CSS code. We'll get into the nitty gritty of what parse time versus computer time means a little bit later. But what I want you to remember now is that we can't actually use @supports to detect @property support.

In fact, I have not found any CSS based way to detect @property, but detecting it with JavaScript is fairly easy. You would just check if there is this global variable called CSS property rule that's the interface that @property rules correspond to in the CSS om. And you could check if that object exists, you would just add a class to the root element.

And then you can use the sentence selectors with @class to vary your CSS depending on whether @property is supported or not, which given its browser support right now, it's still very important. If we use @property, we do want to specify fallbacks as well. Unless it's for something that is very superficial decoration we're fine if it doesn't exist.

But in most cases we do want to provide fallbacks. Another point that confuses people when it comes to these fallbacks is this. So, take a look at this code for a bit. Is this specifying multiple fallbacks and what does that mean? So actually, anything after the comma is part of the fallback.

So this will just give us a yellowgreen. When the fallback is applied, it's equivalent to just having a background of none, yellowgreen, which is just two background layers one without a background image and one with yellowgreen.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now