 Hello, my friend and friends! If you've ever wanted to make a navigation like this one that changes depending on where you are, so you go past a certain point it switches over to a different color or different styling and take that idea and maybe tweak it and make it customizable so you could also do something like this where it sort of slides in with this glass morphism look that's very popular these days and then slides back out as you get to the top with only one navigation we don't need multiple ones in our HTML and we don't even need any JavaScript for this. Well, if that sounds interesting and you want to know how we can do all of this you're in the right place we're going to start by building out this version because it's a little bit simpler I'm going to take that code step it up make it very customizable using custom properties and turn it into something that allows us to do this version here instead so if all of that sounds good you're definitely in the right place but just before we dive into it I do want to let you know that I have new t-shirts there's this one that I'm wearing right now as well as one for grid and another one for color space so you can show off your love for CSS and let everybody know that you're also a friend and friend if you're interested there should be a little card thingy on the video right here and there'll also be underneath the video as well but what you're really here for is learning how we can do the sticky navigation and so let's dive right into it and take a look very quickly at the code that we're going to be starting with here very simple I have a header here which is where most of our styling is going to go it's giving us the navigation that we can see right up there I have an svg as my logo you don't need to have an svg as your logo but if you do want it to shift colors like we're going to be doing it makes it a lot easier if it is one if not you could probably do it with a blending mode or something but using an svg does make it easier and we'll see how that works when we get to it and then I just have my nav here with a ul and all of that and obviously I also have some styling on here nothing too fancy I'm not going to deep dive it if you want to take a look at my styling there is a link to the finished code in the description you will notice also that I'm using nesting here so I just have a few things that are nested if you're not used to nesting this is just a ul that is inside of my header it is modern css which is what we're going to be playing with today which is why I felt comfortable doing it for this demo and right now with everything I have set up all this is doing is giving us a regular navigation that's just at the top of the page we want it to stick first of all so the first thing I'm going to do is I'm going to come here and I'm just going to paste this in where we're getting a position of sticky with a z index of a thousand a background color on it and a top of zero so you can see that has all come in and now because we have the position sticky there it's working the z index here is just because of anything else has a position on it other than the static it's the sticky stuff often ends up behind it so let's just make sure it's on my top layer I've put a big number and the background color I need to have because it's going to be transparent if not which means it's kind of awkward so we can put that back on there now this first one we're going to be doing is when we scroll down it's going to shift and change colors so to be able to do that we're going to do is I'm going to scroll all the way down to be outside of my selector we can't be inside of another selector for this to work because we're using at keyframes which have to be on their own they can't be nested if you're using regular css if you're using a preprocessor it is not a problem and the keyframes here I'm going to call it sticky nav just like that and the real trick here is we just want to put in these styles that we're going to have at the end of the animation and so for now the only thing I'm going to do is put this box shadow on there we're going to tweak this and change it a little bit more but just to show you as a quick example of how this works and normally box shadows aren't something we want to animate they're not the best for performance but because it's linked to scroll position I'm not too worried about the frames per second or anything on this um and then we're going to come back up on the original header up here and we're going to come and we're going to say animation and on here we're going to do our sticky nav which is the name of our animation we're going to say that it is linear because we don't want we want the timing function just to be like from here to here it's based on scroll position and we're also then going to say that we want it to be forwards because when the animation is finished we want it to stay at the end and if I just do that because we don't have any timing on here it's actually already applied which is you can see there there's a box shadow that's on there and you know what I was just thinking this isn't going to be super obvious with just the shadow because we don't really see it here so why don't we actually invert things here a little bit I'm going to move we have my color here I'm going to make this my 100 900 I should say to make it white and then this is going to go to 100 so we have a dark one there and what we can also do is invert those two at the end of our animation so if I bring those down here make that my one make that my nine let's hit save so you can see it's actually we're at this point now we're at the 100% because the animation has just run and that's all it's happening if I wanted to I could even come here and say like two seconds hit save and if I refresh the page it starts dark and you can see it switches over after two seconds but I don't want it to have a time on the animation here instead I want to use animation timeline and I'm going to write in view and it's going to work now but it's not perfect but as I go down here we can see if we look up at the top it's slowly shifting as we move all the way down to the bottom of our page which isn't what we want we want it to basically stay the same and then all of a sudden shift over a short period of time so to be able to do that and what we're doing right now is we're doing it all in sort of the steps so you understand how it's working then we're going to make it a lot easier and less magic numbery as we go through this what we're going to do is after my animation timeline we're going to come in with an animation range start and I'm going to duplicate that one and do an animation range end here and these are for where does the animation start and end there are ways of passing values into here but they're kind of backwards kind of weird if you want to know more about this I have as I said in the intro covered animation timeline and scroll stuff in a lot more detail in a previous video that really deep dives all of this so I'll leave the link to that down below and I just realized my color on this is terrible it's okay well we'll get it looking better later this should stand out not be so dark I don't know what I did but that's okay so animation view timeline is good so the start let's just do for now we're going to say that it's 100 vh for my viewport height and let's come here and say 120 viewport height and what that means is you can see it's shifting in this short period of time right here because it's starting and the start's always an offset so it basically means once it's at so like here if I made this 50 let's just say I mean you can see it's already like halfway done so I want it to be at 100 to be like we're starting from the top of the page basically and then it's going to be finished here so we have like a 20% scroll range sort of thing almost already it's not quite what I want though because ideally I'd want to start switching somewhere like around here once it's already like past this dark hero type area right so we'd stay dark stay dark stay dark then switch so this is where I can feel kind of magic numbery but I can just boost this number up more and then make this one even bigger and now until I've scrolled to about 50 percent of the way down my page it's going to stay that and as soon as I hit that 50 percent scroll mark it's going to start switching and it switches over we're going from 150 to 180 so it takes us like 30 percent so the smaller the difference here if I do that is 160 just means that shift is going to happen much faster when it does make that shift right there there's a few important things that are happening here because I mentioned my logo is changing colors the reason my logo is changing color is because I have the fill of current color and because as I said I used an svg here you can't use the svg as an image here it has to be as an inline svg if you do want to manipulate the fill this way so just so you know that's an important thing to take into account depending on how you're setting things up if you have an image you could probably actually it depends on your colors and stuff so I don't want to say for sure but you might be able to use like a difference blend mode or something to create some interesting effect but ideally if you have an image that's a different color it'd be kind of weird if it's shifting anyway so just be careful with with logo colors but it's following my current color which is my text color and my links are also set to inherent so that's why I can change it on the parent and everything is shifting along with it but otherwise it's actually working pretty good the thing that's kind of awkward with it when it does this shift right now and as I said we're gaining the box shadow is coming in the box shadow animation I'm not concerned about because it is just based on scroll position but the thing that's really awkward right now is that we have these sort of magic numbery setups here and I don't like that they're magic numbery and I want to make it easy for people to modify and to change and what about the colors and everything else that's going on I want all of that to be actually really easy to be able to handle so that's where custom properties come into the mix so what I ideally have is animation starts after and we could say like 500 pixels so once we've scrolled down 500 pixels we're going to start our animation and then we're also going to come in with a custom property here called animation and I guess like distance like how long maybe if you have a better name for that let me know but animation distance and we'll say 250 so we're going to scroll 500 pixels down the page start my animation and the animation range of scrolling is 250 pixels the other thing I'm going to do here and I'm breaking this off on its own little tangent because people always ask me about it is I'm going to make these have an underscore on them just to indicate these aren't things you find up in the like the root these are locally scoped custom properties so I'm sort of setting them apart a little bit this is an idea that lea veru had it's sort of like private properties in javascript there's a little bit more to it than what she was talking about but I just like doing this as a way to delimit if something's a locally scoped property versus if something is you know I go and find it in my route so that's how I'm setting it up here and just why you'll see me using underscores on them so how can we use those numbers let's come down here and on these I'm actually going to use a calc so we can say calc of 100 v vh because viewport height and you could use dvh here if you wanted to as well dynamic viewport height I think vh is actually very safe to use in this case but if you wanted the dvh you could use it as well and with that we're going to say plus 100 vh plus my var and we're just going to copy that because it's faster and paste it in so our animation starts after and then I'm actually going to take this one and copy it again and paste it on this line let's make this a lot bigger so you can see what I'm doing so we're going to say this plus my var and this one is my animation distance so that's just you know we're going from this point to that point basically and this math will work and if I hit save on that now we come back to here as I go down we can see that it's hitting exactly what I asked it to so we're scrolling down that distance then it's going to do the shift and it's going to go to there I'm actually going to make one change here because I don't like how it looks my after color my background here I'm going to make this pure white and I think that little like grayed out zone is going to look a little bit nicer and what I like about this now is I could say okay after I scroll 900 and I can use pixels here or I can use viewport units or I can use whatever I want and just for fun I would never do this but we could say 900 and 900 so that means if I scroll down we have to go all the way down and then it's a really slow shift or we could come in here and make this like 50 pixels here so now instead of a really long transition it's going to be a really short transition when it does happen right and that's probably more of what you're after and again this could be set with viewport viewport height so after we scroll 50 viewport height which would be about 50% of the way down then all of a sudden we're going to get a nice fast transition to having the shadow whatever you want you can play around with those numbers and we can actually make a lot more of this customizable as well if you want to you don't have to add these all in but I sort of like having it like this where I'm also saying like surface color start surface ends that's the background colors and then I can also do the same for my text color start and text color end and so that just means I need to use those within what I'm doing down below but it's just adding all of that customization here so a really quick edit there I've just switched all of those out to those custom properties and then at the end of my animation I've put this here so we have my color my background color going to the end values over here and what I like about that is it means I don't have to come down here and make a change I'm controlling the entire look of what's happening from here and I just the more controls I put as as custom properties sort of the more I like it so we can see that it's still working except I'm getting very transparent which wasn't what I was after because I put a low opacity right there we can fix that and play around with my numbers and there we go that's looking a little bit better I fixed my colors up and maybe this can go up to like 120 pixels or something just so our shift is happening so if you brought this into a project you could set it all up here and everything would be working really good now one thing you'll notice here is I'm doing a surface and start and end I'd find it easier because I can control it all just through here there would be a way to do this with a single custom property and you just change the value of the custom property down here instead I personally like this other method more just because I don't need to go and look for my keyframes after everything is just stored right here but it would be possible the only thing is you'd also have to register it as with like an app property if you wanted to change the value of the custom property and have it animated so yeah if you've never done that there would just be another thing that you'd have to look into it's Houdini app property it's not hard to do but I just find this this much easier and it's also going to help us a little bit with browser support because if a browser doesn't support this what are we going to do right there's there is a polyfill that I haven't experimented with in this you know the polyfill is a little bit limited in what it can do so it would definitely be worth playing with and seeing if the polyfill works but what I'm going to suggest is just coming in and you have to decide do you want it to be a sticky nav or not if browsers don't support this so right now it's only in chromium browsers but it's over 60 support and it's behind a flag in firefox I believe I put links to browser support tables in the bottom but what you could do is just come right here and you could say that at supports and this would just be animation timeline of view and then wrap that entire block let's make this bigger so we can actually see what I'm doing take this entire thing here and wrap it within the the at supports and what this means is you know is this supported or not and if the browser does not support this then it's not going to run through this but we will have a sticky navigation that means the color won't actually change so if I come and take a look in firefox now it's just staying as a dark navigation everything is working no broken experience it just doesn't have that shift going on or maybe you don't like that you want it to be at the end state because you know this only works when it's at the very top you want it to stay sticky of course if you don't even want it to stick then you just move all of this into here right if I do that then in this one it's not a sticky nav it just works the same way it did before so that's obviously an option whereas here because it is supported it's working and everything is fine or the other option is you actually move this sticky nav linear forwards outside of the supports and I'm just doing an alt up and down to move code around um just in case you didn't know that shortcut in vs code and as we saw when we first set this up what this means is it sees this animation and there's no time on it so the time is basically zero so it automatically jumps to the end and that means we always have the end state so we always have it like this and so this is probably gonna be project dependent a little bit in context dependent on what colors you prefer do you want it with the light one I sort of like this with this simple demo that we made here but it really depends on your use case and what you want but browser support is still an issue with this but I think it's one of those things that is as progressive enhancement is perfectly fine and there's different ways that we can progressively enhance it which is perfect you can decide on do you just don't want a sticky nav or do you want it to be the beginning styles or do you want it to always be the end styles so with that said let's look at how we can make this even better so for the better version I'm actually going to make this a dark theme and I'll see you in just one second all right so now we have a dark theme website you can see my text looks better now as well the animated sticky nav is sticking out because of the color shift that I did both the first and second version of this the finished versions will be linked down below just in case you want one or the other and in this case I don't really want this to happen we want to get sort of that new trendy glass morphism style instead so for this there's a couple of fun little tricks and things along the way and we're going to sort of step it up slowly as we go through all of this and so for this to get this started the first thing I'm going to do is the end color I'm going to make this we're going to do I'm trying to think I think I want it black still so five percent but we're going to give it like an opacity of point two or something so it's darker you know it's there but it's it's very dark and my color at the end is going to stay light and I think we're actually going to do light here as well there we go so we just get like an opacity that's coming through on it which is going to work better for the effect that we're going to be after now the real trick here is when I first start scrolling I want the nav to go off with it but then when we reach a certain point I want it to slide in that's the trick for here and the way we're going to do that is actually coming down here to the top and I'm going to show where we're going to later come on and make a toggle so this could be like a feature that you could turn on and off if you want but I'm just going to come to the top and make it negative five rem and the reason for that is before we have any scrolling it's going to just be where it is in normal flow and then as I scroll it will stick but and it shows negative five because it's big enough that our element will be off the screen and it's sticking but it's sticking five rem out of our viewport so we don't actually see it because it's a negative five rem just like if I did this at five rem it's it's sticking but it's it's five rem down so I'm doing the opposite negative five rem and if ever like a little bit is sticking out you can make this a bigger value kind of magic numbery but whatever it's not the end of the world and it's sticking but it's sticking just out of our viewport as we're scrolling down and that means if it's sticking here I can actually change where this top value is and again top isn't normally something you'd want to animate but I'm not after super buttery smooth animations now because it's scrolling position so I don't think it's not something it's like animating in in different ways I think it's okay we could technically translate it in so I think using the top here is okay though so I'm gonna say that my top is now going to be say one rem down and that means you can see it it already worked I'm going to start here and it's there it goes out it sticks and then as I continue going then it's going to animate in and slide back in except now it doesn't look very good so a couple of other things we're going to do let's come back up here and then I'm also going to add in I'm going to do this within my ad supports because I don't really want this on there unless this is supported but I'm going to add a backdrop filter on there because that gives us a little bit of our glass morphism look that we're after and I think that looks a lot better so we'll put in that and again that's just a backdrop filter of blur and then the other thing let's come back up to here and change this color a little bit just maybe a point zero five would actually be enough opacity so it just gives us a little bit of a look to it and it blurs out so I think that's okay the other thing is I don't want it to be as wide and I actually want the logo to be gone and these two things that I'm going to do now aren't really animatable properties so we sort of need to trick things a little bit here to pull this one off and to make it look good and the reason I say that is and let's only put it here we'll do the width first because that one's easier so we're gonna say that the width is fit content and fit content just means like go as small as you can go without any line wraps and if it runs out of room then it will line wrap if you want to make sure there's never any line wraps you could also use max content but then you would get horizontal overflow so it depends which one you want I'm going to go with fit content just because it's slightly safer and of course I've made this not mobile friendly you know I'm leaving that one up to you we're looking at the stickiness right now so there we go that's already looking a little bit better I guess we could also come up to here and add a border radius on all of this I'll just do it here border border radius of 100vw which means it's always going to be a pill shape so right away you can see it's here it's stuck or it's not stuck it's sitting there it scrolls away and then it comes in but notice how it does this weird shift right here where the width is kind of like here it's okay but then it it basically instantly goes from its full width like let's I'll show you let's make this like 300 or 500 pixels or something really big so the distance should be long but it's basically like one it's instantly wide or instantly narrow and that's because we can't animate to a fit content right from auto so width can I do this I don't think I can no same idea we can't go from the width to a fit content to an auto or width 100% that's not going to work so we need to come up with a different way of doing that but I also need to hide my logo so we're going to do both of those at the same time because it's a very similar thing that we're going to do little wardrobe change Kevin from the future here I was watching the my edited version and then realized I did a bit of a contrived solution here it could be a lot easier so we're going to look at the simpler solution that I should have done in the first place for getting the that problem with the sizes and everything to work so what we're going to do is let's do the well as I said we'll do both at the same time and what it basically involves is let's find my where I have my logo set up here where I just have the fill and I have a height on it because it sort of makes sense for a logo I'm going to do a display on here as well and my display is going to be a custom property that I'm not going to have defined which is going to be a logo display and I'm just going to do a comma and actually I put none there but I want block so what that means is my my logo display is set to block by default because this is an undefined custom property so just means if the browser can't find a value for that it's going to use this as the value and the reason I want to do that is because then I can actually switch it within my animation because we can't I don't want to have to have multiple different animations I want this one animation to be for everything and so by having it as a custom property that makes it a little bit easier and I don't even need to worry about doing this as a registered custom property with like an app property or anything like that because we're not animating this it's just going to instantly change right we're going from block to none instantly so that's going to be set there and we're going to do the same thing for the width where I can come up and I don't have a width set anywhere on my header right now but we can do the same thing where on this we can come up with a width and this one doesn't technically need to be a custom property because the animation is directly on here but it just makes it a little bit more obvious what's happening I think so I'm just going to call this one header width and the default will just be auto which it already is this is the value we're what we have right now and we're going to save that and the reason I'm doing that is because I want to come down here and change them there is a catch to this though and we'll see here and well we saw that already with the width where it wasn't really working properly right because if we have the when we change I can change my custom properties here so if I did the header width and we'll do the logo display as well so here I can change this to be my fit content like we were just playing with and then I'm also going to do my header display and make that none and that just means that the my header display is not working oh not header display that should be logo display sorry and so it's that same problem we have where it's like halfway through the animation we're switching from this to the other one so instead of doing these here we're going to do them somewhere else because we can have different key frames set up and here I'm going to do a zero percent one hundred percent instead and throw them in there and that just means that these are going to switch as soon as the animation starts and why this is going to work is because the animation is starting when our logo is stuck five rem off the top of the page so because it's happening off the page it just seems to slide in and everything is perfectly fine and good and there's a few extra things we could do here just to make it a little bit more customizable as well so if we go all the way back up to here just like I have these set as my custom properties but what we could do is set things here that would be sort of like settings so again we wouldn't have to jump down to the other area down below right this is our settings that we want to keep so I could say a logo after animation is it so we could have it stay block or we could have it go to hidden and then because we have this here what we could do is we could come down all the way to inside the animation where I have the none here and I could have that look at that other one so this would be my logo after animation or maybe you can come up with a better name for and we could do the same thing for the fit content for the width and you could do the same thing with your border radius and other things like that so you'd sort of pass off all the different things that would end up being down there and I put hidden here but we want to have it as none right so if we do that it should still work perfectly fine you can see there we go so it's switching over to this but only in the second half and I like doing that as much as possible again so I don't have to look up here for some stuff and then go and find a keyframes animation somewhere else the more I'm controlling here the better so I'd encourage you to play with this a little bit make it more of your own you can add some more customization to it and so if you did enjoy this video and you'd want to do a bigger deep dive into the different types of things you can do with the animation timeline and we have a scroll and a view and there's a lot of different controls and different things we can do with it and really fun effects that we can create without any JavaScript now which is always very exciting especially for someone like me but if you're interested in that that video is right here for your viewing pleasure and with that I would like to thank my enablers of awesome Philip Andrew Simon Tim and Johnny as well as all my other 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