This custom property trick solves a common CSS problem
Key Takeaways
Explains a custom property trick to solve a common CSS problem
Full Transcript
Nothing is more frustrating than wanting to use a CSS feature, but then realizing it has limited browser support. But, my front-end friend, just because browser support isn't perfect, doesn't mean we need to abandon ship. So, here I have this button set up, and it has this, I guess, satisfying bounce effect. I find that really satisfying. I actually only want this to go in one direction and not both, but it's going to help illustrate how we're doing everything, so we'll fix the animation toward the end of the video. Uh, but for now, we're going to leave it like this. And if we come and take a look at it, I'm using this linear function to be able to do it. And this is ridiculous, right? First of all, the linear function is amazing, but holy moly, is that is that a lot of steps that are along the way there? And while support for the linear function is actually pretty decent at this point, it's not perfect, and we do want to make sure that the animation looks okay for people where it isn't supported as well. So, the first thing I'm going to do is actually grab this entire thing. We're going to remove it from here. So, we're just transitioning our scale over 0.75 seconds. And then here, I'm going to add in my transition timing function, and by using the longhand, it just makes my life a little bit easier, uh, to override if I need to. So, I'm going to drop that linear back in there, specifically on the timing function. But then, what I'm going to do is I'm actually going to let's copy this right here. I'm going to come in with a second one that's right here. And just to illustrate that it's working, I'm going to do a linear, which is not the fallback I would want, but just to show what would happen is right now, my bounce is working, cuz in this browser, this is supported. But what happens, because of the way the cascade works in CSS, is if a browser comes across the timing function here, and it doesn't recognize this one with the linear function, it just won't apply that. It would get crossed out type of thing when you look at it in your dev tools, and it would use this linear one instead. So, it's going to the last declaration that it deems valid. So, in this case, if that didn't work, then we would get this instead, which is not at all what we want. And there's actually two problems here. When we don't have the bounce, it's way too slow, and also, when we don't have the bounce, uh, we probably don't want linear. So, maybe you just do like an ease in out or something. You could come in with maybe a curve or something else, uh, that could be the fallback that you would be using in this case. Uh, and then when the browser supports it, like mine does now, we get the nice little bouncy effect. So, first of all, the easiest thing to do here would actually be to come and come up and I'm going to grab this as a custom property. So, we can come all the way up to here and it doesn't have to necessarily be in the root, but I would probably do something like spring or spring animation or spring timing function. And we could have that there. And I might even do that as spring timing function and we'll I'll explain why I'm doing that in a second with the full thing written out. Or actually, we'll cover that right now cuz I'm also going to come in here with a spring duration duration to make all of this sort of work and we said that was a 0.75 seconds when we have the spring in place. And if we come down to here, now the first thing obviously is this can now become a var. And we would do my spring timing function, just like that. And in this case, we could also do it within the shorthand, that would work fine, but I'm going to leave it as the longhands here. And then we'd get that same type of thing happening. If this isn't there, then it would come to this. One thing you cannot do here, if you're thinking about using custom properties and you're like, "Oh, I want a fallback value." is you cannot take this ease-in-out and use that as a fallback here. Or you wouldn't even be able to leave it as something before that. Because when a browser comes across a custom property, and just to actually we can show you that how this would work. Let's come up and change this linear function to be something that wouldn't be considered valid. We're going to write purple here. Uh, so if I write purple as my timing function, that's not a valid timing function. But with custom properties, when you have fallbacks, it's not whether they're valid or not for the property you're using them for, it's just does this exist or not? Because custom properties can be anything whatsoever, right? So, if we come and take and look in here, my spring timing function is purple. That's completely valid. And then, if we come and take a look on the button itself, we see that our my spring timing function is not defined because I didn't spell it correctly, Funk function. It helps when you spell things correctly. Uh so now you can actually see that it's using the spring timing function and I even see the purple that is right here. So it's not using the fallback, it's going to use this. However, let's just remove this really fast and let's just write purple here. Uh purple. And we can come back in with that. If I come take a look at it now, it's getting crossed off cuz purple's not valid. So it's a really important thing when you're using custom properties, you can't rely on this type of behavior to actually work. So that's that's the first thing uh right there. So I'm going to come back to just having my spring timing function this way. And if we can't do it like that when we're using a custom property, how can we actually do it? And before we do dive into the specifics of how this is going to work, I do want to give full props to Josh Comeau for sharing this tip. This is I got it from him. He posted over on Blue Sky about this and I talked to him and he's like, "Oh yeah, make a video on it. No problem." Uh so thank you for Josh for sharing it and letting me make a video on this. And if you don't know Josh, I put a link to his blog in the description which is full of some of the best blog articles you'll read with really awesome interactive examples and other stuff in them. So definitely check it out if you don't already know about his uh blog. So, let's see how we can fix this though cuz you're already clearly following Josh. You don't need to jump on over there. If you do, go after the end of the video so we get the watch time on here, of course. Uh where we want to come back in with our our linear up here. So I've dropped that here and what I'm actually going to do is I'm going to come in with an @supports. And we're going to say @supports. And if you don't know about @supports, it's a feature query. So you generally here would give a property value pair. So here we can say a transition timing function. And here we just say linear. And you don't have to put the whole thing, you can just put any valid one. So we can just do like a 1 2 3. That would be a valid timing function. So as long as this if the browser supports what it sees here, then it's going to use these custom properties here instead. So if I do that and let's just come down here and also update. We can say this is my var uh spring duration as well just so we're using both of those values. Dure- shun. There we go. Uh and now we can see it's working both ways. And let's just come here and say this was like a different thing. I don't know. Uh even if I just did this, I'm not even sure would this work? Yeah, so now because this isn't valid right now, you can see it's not supported. So this is what the fallback currently is. And this is not what we would want the fallback to be. I want some sort of animation there. All we have to do is come here and have a regular declaration within our custom properties. So here, this might be like a 0.25 seconds and here we do our let's say our ease in out. So in browsers where the timing function isn't supported, it's going to look a little bit like this. And the shorter time on this is much better, right? Cuz if you have the 0.75 on there, like that's really long for how long that's going to take when there's not that popping thing going on. It doesn't look springy. It's just this really long time going on there. So we can come in with something a bit snappier or maybe even a 0.125. Make it really nice and snappy. And then here, when a browser does support the linear function, when I do it, now we get the nice spring going on right there. And I think that looks a lot better. And actually works really well. So I'm happy with that. So now anytime you need your spring, you just use your spring duration, your spring timing function, and you know that it's going to work and you don't have to repeat doing this thing where you're repeating it twice. This is almost like a mixin that we not quite, but sort of that idea of the fallback is built into this custom property, which is really, really cool because of the @supports. Uh two other things that we want to look at. One of them is just I mentioned we can improve this. So one way we can do it or maybe debatable whether it's improved or not, but just so you know, you can definitely have different transitions in and out. So maybe I only want the spring in one direction. So here I could change my uh transition timing function and just say that here when it's active, so that's when it's being clicked on, whether it's with your touch device or when I'm clicking on it with my mouse. Uh we could say this is an ease in. And now it's going to be really slow once again, but then it bounces back out. But then we could also come in with our transition duration and maybe do our 0.125 or a 0.25 seconds or something like that. So we get a regular push in and then it bounces when we let go. So if ever you want sort of a different thing in the two directions, we only want the spring when we're releasing, we just have it set up like this. So that's kind of handy. So I just wanted to cover that really quickly cuz I sort of wanted this effect originally. And the other thing I want to look at is another use case for doing this, but instead of using at supports, it's using a media query. So it does depend on the type of feature that you want to be looking at. And so for that example, it's looking at my brand here where I have this set as an HSL for the purple color I have. And I can come in and I can use an at media with this color gamut P3 and come in with a P3 color, which is going to be a brighter color on devices that support it. My computer does not support it. So it's going to use the fallback here. P3 colors will by default fall back, but now you can make sure you're getting the fallback color you want as an example here. Uh and the reason I'm not using an at supports is because I and you could definitely do an at supports for this the same way I was doing it here. But in this case, my browser supports P3 color, but my device does not support it. Or actually I have it turned off cuz it's make makes the whites way too bright on my computer and it blinds me. Uh and then if I turn down the brightness, it just washes everything out. So I don't use the more vibrant colors on my device, but this would also be on phones and other things where they tend to be So on devices where it is there, you'll get a more vibrant purple that's probably closer to the brand color or something like that. Or maybe you just want a really bright neon green or something. Uh you might use something like this where the device supports it and then have the fallback outside of the media query there. So another quick example of the same type of way we can do it. You just use your brand variable the same way you've always done before and it's going to give you whichever of these colors is supported by the browser. And also just really fast, one of my favorite use cases for these more springy type animations are actually with things like this, where we're sort of bouncing to open and close things. I just find it really, really satisfying for this, and I feel like it gives things a little bit of extra weight and everything like that. Uh and to be able to do things like this, I'm actually transitioning the height using a linear function here, going to a height of auto. And this is made possible because of interpolate size allow keywords. And if you've never seen this before, it's not something that you could use that trick we looked at now. It is relatively new, and we can't use that custom property trick I just showed for you for this one. Uh but it is a perfect candidate for a progressive enhancement. So, if you want to learn how this type of thing can work, and what just what interpolate size allow keywords even is, well, you can check out this video right here. And with that, I would like to thank my enablers of awesome, Andrew, Simon, and Tim, as well as all my other channel members and patrons for their monthly support. And of course, until next time, don't forget to make your corner of the internet just a little bit more awesome.
Original Description
Having to worry about browser support stinks, but thanks to a simple custom property trick, there’s a really easy way to create fallbacks for older browsers.
🔗 Links
✅ Josh’s website: https://www.joshwcomeau.com/
✅ Josh’s Bluesky Post that I mention: https://bsky.app/profile/joshwcomeau.com/post/3li3r6i7dac2w
✅ Easing Wizard: https://easingwizard.com/
✅ Final Code from this video: https://codepen.io/kevinpowell/pen/vEYvBJd
✅ Animating/Transitioning to and from height auto:
✅ I’ve got free and premium courses: https://kevinpowell.co/courses
⌚ Timestamps
00:00 - Introduction
00:10 - What we’re starting with
00:40 - Using the cascade to our advantage
03:00 - You can’t have a fallback to the custom property as a fallback behaviour
05:33 - Josh’s post
05:08 - Using custom properties to make this much easier
07:18 - Different transitions in different directions
08:12 - Other use cases for this
#css
✉ Keep up to date with everything I'm up to https://www.kevinpowell.co/newsletter
💬 Come hang out with other devs in my Discord Community https://discord.gg/nTYCvrK
⭐ Are you a beginner? HTML & CSS for absolute beginners is for you: https://learn.kevinpowell.co
🎓 Start writing CSS with confidence with CSS Demystified: [https://cssdemystified.com](https://cssdemystified.com/)
🚀 Already mastered CSS? Check out my advanced course, Beyond CSS: https://www.beyondcss.dev/
---
Help support my channel
👨🎓 Get a course: https://www.kevinpowell.co/courses
👕 Buy a shirt: https://cottonbureau.com/people/kevin-powell
💖 Support me on Patreon: https://www.patreon.com/kevinpowell or through YT memberships: https://youtube.com/@KevinPowell/join
---
🧑💻 My editor: VS Code - https://code.visualstudio.com/
🌈 My theme: One Dark Pro Var Night
🔤 My font: Cascadia Code
---
I'm on some other places on the internet too!
If you'd like a behind the scenes and previews of what's coming up on my YouTube channel:
Bluesky: https://bsky.app/profile/kevinpowell.co
Codepen: https://cod
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from Kevin Powell · Kevin Powell · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
How to create an awesome navigation bar with HTML & CSS
Kevin Powell
Improve your CSS by Keepin' it DRY
Kevin Powell
HTML & CSS for Beginners Part 6: Images
Kevin Powell
HTML & CSS for Beginners Part 7: File Structure
Kevin Powell
HTML & CSS for Beginners Part 4: Bold and Italic text and HTML comments
Kevin Powell
HTML & CSS for Beginners Part 5: Links
Kevin Powell
HTML & CSS for Beginners Part 3: Paragraphs and Headings
Kevin Powell
HTML and CSS for Beginners Part 1: Introduction to HTML
Kevin Powell
HTML and CSS for Beginners Part 2: Building your first web page!
Kevin Powell
HTML & CSS for Beginner Part 8: Introduction to CSS
Kevin Powell
HTML & CSS for Beginners Part 9: External CSS
Kevin Powell
HTML & CSS for Beginners Part 10: Divs & Spans
Kevin Powell
HTML & CSS for Beginners Part 11: Classes & IDs
Kevin Powell
HTML & CSS for Beginners Part 12: The CSS Box Model - Margin, Borders & Padding explained
Kevin Powell
HTML & CSS for Beginners Part 13: Background Images
Kevin Powell
HTML & CSS for Beginners Part 14: Style Text with CSS
Kevin Powell
HTML & CSS for Beginners Part 15: How to style links
Kevin Powell
HTML & CSS for Beginners Part 16: CSS selectors and Specificity
Kevin Powell
HTML & CSS for Beginners Part 17: How to Create and Style HTML Lists
Kevin Powell
HTML & CSS for Beginners Part 18: How Floats and Clears work
Kevin Powell
HTML & CSS for Beginners Part 19: Colors with CSS - hex, rgba, and hsla
Kevin Powell
HTML & CSS for Beginners Part 20: How to center a div
Kevin Powell
HTML & CSS for Beginners Part 21: How to create a basic website layout - the HTML
Kevin Powell
HTML & CSS for Beginners Part 22: How to create a basic layout - the CSS
Kevin Powell
How to Create a Responsive Website from Scratch - Part 1: The HTML #Responsive #HTML5
Kevin Powell
How to Create a Responsive Website from Scratch - Part 2: The Header and Hero area #Responsive #CSS3
Kevin Powell
How to Create a Responsive Website from Scratch - Part 3: The About Section #Responsive #CSS
Kevin Powell
How to Create a Responsive Website from Scratch - Part 4: Building a Responsive Portfolio Section
Kevin Powell
How to Create a Responsive Website from Scratch - Part 5: Call To Action and Footer #CSS #Responsive
Kevin Powell
Tutorial: Learn how to use CSS Media Queries in less than 5 minutes
Kevin Powell
End of the year upate and what's coming to my channel to start the new year
Kevin Powell
Create a CSS only Mega Dropdown Menu
Kevin Powell
CSS Tutorial: Outline and Outline Offset
Kevin Powell
CSS Blending Modes
Kevin Powell
Parallax effect | 2 different ways to add it with jQuery
Kevin Powell
CSS Units: vh, vw, vmin, vmax #css #responsive #design
Kevin Powell
How to Create a Website - Complete workflow | Part 01: Intro + Setting things up
Kevin Powell
100 Subscribers speed coding bonus video
Kevin Powell
How to Create a Website - Complete workflow | Part 02: The Markup #HTML
Kevin Powell
How to Create a Website - Complete workflow | Part 03: Sass Variables and a Mixin #Sass
Kevin Powell
How to Create a Website - Complete workflow | Part 04: Setting up the hero and header
Kevin Powell
How to Create a Website - Complete workflow | Part 05: Typography & Buttons
Kevin Powell
How to Create a Website - Complete workflow | Part 06.1: Building the navigation with Flexbox
Kevin Powell
How to Create a Website - Complete workflow | Part 06.2: Making the nav work with jQuery
Kevin Powell
Redesigning & Coding My Website #CreateICG
Kevin Powell
How to Create a Website - Complete workflow | Part 07: Starting the flexbox grid
Kevin Powell
How to Create a Website - Complete workflow | Part 08: Promo & Problem shooting!
Kevin Powell
How to Create a Website - Complete workflow | Part 09: The CTA and Footer
Kevin Powell
How to Create a Website - Complete workflow | Part 10: Making it responsive
Kevin Powell
How to Create a Website - Complete workflow | Part 11: Making it responsive con't
Kevin Powell
How to Create a Website - Complete workflow | Part 12: Putting the site online
Kevin Powell
Create a Custom Grid System with CSS Calc() and Sass
Kevin Powell
CSS em and rem explained #CSS #responsive
Kevin Powell
Should you use Bootstrap?
Kevin Powell
How to add Smooth Scrolling to your one page website with jQuery
Kevin Powell
Let's learn Bootstrap 4
Kevin Powell
How I approach designing a website - my thought process
Kevin Powell
Build a website with Bootstrap 4 - Part 1: The setup
Kevin Powell
Build a website with Bootstrap 4 - Introduction
Kevin Powell
Build a website with Bootstrap 4 - Part 2: Customizing Variables
Kevin Powell
Related Reads
📰
📰
📰
📰
I built a landing page with Three.js, vanilla JS, and zero frameworks — here's what I learned
Dev.to · Ayush Shekhar
Part 1: Why I Rarely Use useEffect Anymore (and what I use instead)
Dev.to · Alejandro
HTML Canvas Cheat Sheet for Pixel Art & Image Effects
Dev.to · lemon
Draw Pixel Art with Vanilla JS — A Step-by-Step Guide
Dev.to · lemon
Chapters (8)
Introduction
0:10
What we’re starting with
0:40
Using the cascade to our advantage
3:00
You can’t have a fallback to the custom property as a fallback behaviour
5:33
Josh’s post
5:08
Using custom properties to make this much easier
7:18
Different transitions in different directions
8:12
Other use cases for this
🎓
Tutor Explanation
DeepCamp AI