Create direction-aware effects using modern CSS
Key Takeaways
Creates direction-aware effects using modern CSS techniques
Full Transcript
hi there my friend and friends the other day I recreated YouTube's tab animation for the underline when you go on the different tabs the line sort of stretches and moves across and I had a lot of fun doing that but just after creating that I saw a video in the CSS weekly YouTube channel where Zoran did a directionally aware effect for a navigation menu that I thought looked really cool and a sweet deal I will show you how to use it to create a direction aware hover effect and that got me wondering if I'd be able to recreate that underline effect from the YouTube tabs but with something that's CSS only and directionally aware with hover and focus effects instead of having JavaScript involved in it and this is the final effect that I finally came up with I think it looks pretty cool I'm really happy with the finished result so in this video we're going to be diving in and taking a look at how I did this and it's just a fun exploration of a lot of really fun things and so let's dive in and take a look at how I did it and this is what we're starting with but just really fast before we get into it just in case you're new here my name is Kevin and here at my channel I help you fall madly deeply in love with CSS and just web development in general and if I can't get you to fall in love with it I'm hoping to at least help you be a little bit less frustrated by it so let's Dive Right In Here where you can see I have this really simple navigation setup the same type of thing you see on basically every site ever right and we're going to be playing around with this a little bit in my CSS I haven't done very much I just put a big font size on because it's a demo I'm using on the UL I have a display of flex here just so they go next to one another and then I have just a basic styling on my links and I'm being lazy and using opacity to change the color because I'm being lazy and I didn't want to have to pick colors if we want to look at how we can get that directionally aware CSS goodness to be happening on here now the very first thing that we're going to do is I'm using a gap here to create the spacing and it's sort of the normal approach I would take but in this case I'm actually going to replace that with a custom property called Gap because I want it to be really obvious that this is the gap on my UL so I'm going to go with the same name now I'm putting an underscore here this is just to indicate that it's a locally scoped custom property and not something that would be coming from the root so don't go look for it there if you see the underscore it's something locally scoped and doesn't live in the root so with that Gap I'm actually going to use that on my Li's and I just realized like here I didn't put nav like this is a really simple example I'm not using classes or anything but I guess we'll stick with it being a little bit um more semantic in a sense so we'll do a nav Li just to make sure we're only in our navigation but of course you could replace these with classes or however you want to be working so on these allies what we're going to say is we're actually going to give these some padding and I'm going to say the padding is my I'm going to do a calc burst and then we're going to say VAR Gap with the underscore just like that and it gives me the spacing in between them again the only problem is the spacing is twice as big as I want it to be because there's two REM of padding here and then two REM of padding back on that side so that's why I put a calc there just to do a divide by two and it goes back to how it started so now it's one one REM on this one one REM on that one but the reason I bothered doing this is it just makes it a little bit easier for the like how big our underlines should be once we get these underlines coming in by having this on the padding so there's if you want to take a different approach for getting that spacing in there by all means you could definitely do it but for me this was the easiest now what I actually want to do on these is we're going to do an AV Li after and on the after here I don't know why we got a top but there we go uh we want our after and because it is a pseudo element we do need the content property on there and let's give it a height of say three pixels position the position of op position absolute and then let's give it a background color background I'm going to go with orange red because it's a nice color on this dark background and then let's also give it a width of 100 but of course I don't want these values to be for the entire you know right now they'd be looking at the body we get these huge lines that are showing up which I don't want so I'm going to go over to the individual Li here in the safe position is relative relative kind of spell things right and then we get them all matching the size of their the parent so the pseudo element is looking at the individual parents to figure out their size uh which is awesome but now obviously we also want the left to be a0 so they line up properly there and we'll go in with a bottom of zero as well so they're right there I just realized this padding is on my top bottom left and right um and I'm using it as my Gap so we might want to just update this and say padding inline just so uh you know it's actually a working like the Gap and then the bottom here maybe it could be a negative one ram just to pull it down that distance now with this it looks like it's one big solid line but of course if I came in on these widths and I said 50 or something each one of these allies actually has its own line coming across but because they're all at 100 percent they're sort of connecting to each other as they stretch along and that for me is a good thing and that's why I have this as the padding here because if we'd had just throw a gap on here gap of one REM let's say then it would add that space in and I'd sort of have to play around a little bit with um and you just be doing probably a calc to sort of pull you know you could do your width and then add it in and then with your left and right so what ever there's other ways of getting the same type of effect I just found this one was a little bit easier to do so they all sort of connect to one another now before we worry about making it directionally aware I want to get the hover effect when I just go on one of them that it's going to appear from the middle and that's the easy one to do so here on the after I'm actually just going to come on and we'll come down here and we'll say scale is going to be a zero one and they vanish so scale is its own property you could do this also with the trend with you know the transform and then we can have a scale here scale and you could do it that way as well and I'm going to be using different Transitions and delays on them so it just makes my life a million times easier if I make that the scale and just to show you that they're there we can do a 0.5 um so we're shrinking at 0.5 on the x-axis but zero on the y-axis so they keep their height but we're shrinking them this way uh and then what we could do is we'll keep it 0.5 for now and I'm going to copy this and we can come in and I want to say when I hover on maili and I'm doing this on my alive the link is in there so it should be fine um so we can say hover and I guess you could do all of this on the link itself as well instead of on the list item it wouldn't really change a whole lot let's just take our scale here and do a one so now if I go on any of them it goes back up to the original one so we can bring that to zero and then anytime I hover it's growing but it's instantly growing so we can also transition our scale and for now I'm going to say 250 milliseconds we can change that after but at least we get this type of thing happening which is the initial behavior that I want and this will actually be the fallback as well so if a browser doesn't support has which we're going to have to be using they're going to get this Behavior anyway so it still works and still looks pretty good but we're we'll step things up for browsers that do support has which at this point is is pretty good actually the support on it now what I'm actually going to do for the moment is I'm going to bring the scale back up and turn them all on but I'm also going to come here and I'm going to say Li and child of three just to select the pricing one uh because it's gonna be a lot easier to understand how this is working if we just look at one of them sort of moving around and everything and then afterward we'll turn it back on for all of them but just for visualization purposes this is going to make a lot more sense so we're just going on the LI that's the third child so one two three that's my third Li the pricing right there so what I'm going to do is I want it to stay in the middle because we want that initial Behavior right we want it to do this most if somebody just happens to hover on that and they weren't on one of the other siblings first that's the behavior we want so as a default this is this is perfectly fine we're going to leave it like that if somebody was on about first and they move on to pricing I want the line to come sort of up look like it's moving over from the about over to the pricing so this is what we can do here and this is kind of fun we're going to say nav Li hover plus Li and for now let's just say color is going to be let's do hot pink because hot pink stands out so now if I hover on any of them you can see the next one over is changing over to Pink so it's if I hover on a list item that's in my navigation the adjacent sibling so the next li over will change color so we can see it's working now obviously that's not what we want what we want to do is select the after here and actually we'll look at a way we can sort of clean this up with custom properties a little bit in a second but let's just do this really fast and then we'll we'll do that next thing of cleaning it up with the custom properties and so what I'm going to do here is let's take this off we're gonna do a translate we're going to say negative 100 and so now if I hover on there you can see it's moved over that way and then we want it to be that you know as I go to pricing it's going to slide over so let's come up to here and on we have the transition for our scale and what we can do now is we can also say that we're going to do a translate and we'll do 250 milliseconds here as well so we have both prettiers coming in and and doing that just to keep it all we have a scale and the translate there so now when I'm here that red line is going to be over there and when I move over it's going to jump to there interesting right so if we slide over as we go that way now to really get this effect to work on my li we can also say that we have an overflow of hidden and now it's completely vanished and actually that's because I did the bottom here I just wanted to move it down well go with the bottom of zero on there so it pulls it back in um and so we have the pricing there and when I go to here it's moving over that way and then I can so it's actually you know if we don't have that overflow hidden on there it's moving over but because of the Hidden is on there it's it's vanished and when as I come here it slides in kind of neat right now this is nothing incredibly new but what we can now do with CSS is we can actually choose preceding siblings and this used to never actually be possible but thanks to has it is so let's come here and actually yeah we'll do it first and then I'll clean up with custom properties like I said I was going to do so in this case now what we're going to do is we're going to say in nav Li has Plus Li hover and we don't need the LI there actually we can just say plus hover so if the sibling after it is hovering we can do something to that one before so let's just come here and say the color is hot pink once again so we can see that if I go on something the one before it is changing right so that's kind of cool that's and this is what enables this magic to happen and so now we can actually do is come in on the after on that one and we can do a translate bit in the other direction so let's say this is actually me positive 100 let's go turn off that overflow for a second I will comment that out and so if I go here it moves that way and if I go there it moves that way and this is really where the magic is if we do the Overflow hidden now and let's turn our scale back on to zero so it's vanished if I hover on top the scale is coming in but then if I'm here right where we're we're moving over to the blog we're going that way and then it's going to slide in that way and now if I'm on this one and I go that way it slides in from that direction so we can slide in depending on which direction we're on and so let's just take this off from being the nth child we can do this on all of them right so if I come from the top or the bottom it does that and if I slide over the whole thing sort of shoots over now it's not perfect yet I want to fix up this animation just a little bit because right now it's a little bit clunky sort of how it's working because we have it sliding and shrinking and there's a few things happening at the same time that are making it look a little bit sort of like it's jumping to the next one which is already kind of cool it's not bad but what we can do here just to make like this section A little bit easier to look at where we're always having to select these Afters let's come here and we're actually we're going to do a translate here so let's say translate and we're going to say that the translate is going to be VAR Translate and I'm going to do a zero zero as the default so the translate as a default is zero and then here what I'm going to do is on this one we're going to do a VAR scale and actually you know what we could even call this VAR width um just and the reason we could call that width is even though we're doing it on the scale the whole point of this is to control like the width of our element so let's let's call it width there so now what I could do is I could actually come here and remove this and I could remove all this and I could just say that the width is now going to be a one uh I just realized it's very broken so we should give this a default so the default will be a zero uh so we have no width and then when I hover on top of them they will get that width of one that's coming here then over here what we could say is instead of having the after we could just say that our Translate we have our translate can go to negative 100 let's just copy this paste it here we can take the after off again and we have the positive 100 in this direction so we still get that same behavior that's happening I just find this a little bit easier to be able to do it and we're going to be making a few other changes on these as well so not having to select the after every time I just find it cleans up the code a little bit um and and makes it a little bit easier so that's why I'm doing it like this now the other thing I'd like to change is actually on these animations and is to delay them a little bit too so let's come in here first and let's change this one to about 300 and we're going to change this one up to about 500 and then after that I'm also going to come and add a delay to them so here I'm going to do a VAR of scale delay and I'm going to do this as a default of 0 Ms and if you don't put the MS here I do believe it breaks it because um we can't use its animations and transitions are one of those places where xero does still need a unit and let's see this one is translate delay and if I was doing this you know as my own I might do TD just an SD just to make it a little shorter but we'll keep it really explicit here so if you go get the code after you know exactly what these are being used for so there we have it we have the transition delays and all of that so for now right away you can see it's it's still working and the big thing is when I go from here to here I actually want it to start moving before the scale comes in so I don't really want to delay so for that that would actually be on both of these we could combine these into one but what for now let's just do a scale scale delay and this will be let's say 300 milliseconds and the reason I'm doing 300 is I'm using that number here this could be another use case for a custom property as well just so you have the same number coming for both of them and let's take this same scale delay and put it on this one it's going to start sliding over before the scale kicks in so instead of doing the thing where as soon as you go off it was like scaling and moving um I found it a little weird now it does still have this weird sort of little like clunkiness going to it maybe you like the feeling of it and now we'll do is we'll come in with a translate delay and I'm going to do about 200 milliseconds and we can do that for both of these so if I do that now when I look there and then I go here see how it like it stretches over and then it shrinks right because we're delaying the we're delaying everything basically we're just making sure that that translate doesn't start happening until there's a bit of like time and the other one's already come in so it just gives us a bit more of that like gooey feeling that we are we're after and a little bit more like that YouTube One um that we were doing and I sort of want a little bit more distance here and as we saw if I move it with my bottom the Overflow hidden will hide it so I think I'm actually just going to take this padding in line and make it padding everywhere just so we have a bit more of a gap and I think that looks a little bit nicer so that's looking pretty good I'm really happy with that and the reason again if I was just doing like my width um and maybe if I was only doing my translate and the translate here I probably wouldn't bother with the custom properties and breaking it all down but because I find it a lot easier to say like I'm just doing my scale delay it might translate delay and breaking these pieces up a little bit like this I find it a lot easier uh to do it with the custom properties and then you don't have to bother with the hovers like I said uh The Afters I should say now as far as supporting this across different browsers all of the fancy stuff is basically happening in this area right here so uh and it's really the has that we we don't want right this is what we have to check for support for so I'm gonna do an at supports and then we can do selector and then I'm gonna say has and we can just put anything here right if has H1 if the browser is able to do this then what that means is we're going to do all this fancy stuff right here so we'll paste that in now I'm in Chrome right now so it should continue to work and we can see it is working because it has H1 is supported by Chrome currently in Firefox though has is behind a flag so if I come and check this out in here you can see it's going back to the old way of working where it was always growing from the center the reason I want to bother with that is just because if I didn't do that the has supports thing here and we look at it in Firefox this way is going to work but if I go over in One Direction it will sort of work right we're getting like the weird movements coming from different ways um and it's not consistent with how it's working and it just feels kind of awkward because it only works in One Direction but not the other direction so just by wrapping anything that like makes the direction related stuff in this at supports means that if it's supported it's supported if it's not supported yeah then it's not supported there is another downside to this in general which is if I go here and I go really fast we sort of get this type of thing happening this is the CSS Only Solution this is the type of thing that can happen it's never going to be a a perfect solution and I did mention uh Focus as well so this actually doesn't work super well uh when we're focusing so what we could do is we could just come here and give this a fallback as well I do have obviously if I do it now we have like the defaults but we could say here is nav Li and we can't focus on the Allies but we can't we are focusing on something inside those allies we can do a focus within and so now if I tap across we get that default Behavior where it grows from the middle it sort of works if you do it on the inner parts here but it wasn't working exactly the same so for me this is sort of like the safer bet for Focus dates and then we can keep this here again when I push this production maybe not just because of this type of behavior that could happen but I still think it's a really fun effect and I really hope that you learned a lot of really fun things along the way with this as well now I definitely would recommend you check out the CSS weekly channel so I've linked that down in the description and if you'd like to learn more of the really cool things you can do with Haz including this sort of gallery effect where you're affecting every item except the one you're hovering on then you can check out this video right here and with that I would like to thank my enablers of awesome TT lld Andrew James and Rico Michael 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 corn on the internet just a little bit more awesome
Original Description
🎓 Did you know I have courses, including several free ones? https://kevinpowell.co/courses?utm_campaign=general&utm_source=youtube&utm_medium=direction-aware-hover-effect
Modern CSS is opening up some really interesting CSS-only solutions, including directionally-aware effects! In this one, I look at how we can do a directionally-aware hover effect for a navigation similar to the YouTube tabs I looked at recently, including dealing with browsers that don’t support everything we’re doing in this one.
It’s not a perfect solution, but there’s still a lot to learn by building something like this 🙂.
🔗 Links
✅ CSS Weekly: https://www.youtube.com/@CSSWeekly
✅ The CSS Weekly video that inspired this: https://youtu.be/abzMSYsnXV4
✅ My clone of YouTube’s tabs: https://youtu.be/h2AOXBeVrgI
⌚ Timestamps
00:00 - Introduction
0:50 - What we are starting with
01:37 - Using padding instead of gap
03:10 - Adding the underline with a pseudo-element
05:12 - Adding a basic animation on hover
06:50 - Making the line move to the right
09:35 - Making the line move to the left
11:28 - Cleaning things up with custom properties
12:50 - Improving the animation so that it slides
15:50 - Browser support for browsers that don’t support :has()
17:05 - This isn’t perfect!
#css
--
Come hang out with other dev's in my Discord Community
💬 https://discord.gg/nTYCvrK
Keep up to date with everything I'm up to
✉ https://www.kevinpowell.co/newsletter
Come hang out with me live every Monday on Twitch!
📺 https://www.twitch.tv/kevinpowellcss
---
Help support my channel
👨🎓 Get a course: https://www.kevinpowell.co/courses
👕 Buy a shirt: https://teespring.com/stores/making-the-internet-awesome
💖 Support me on Patreon: https://www.patreon.com/kevinpowell
---
My editor: VS Code - https://code.visualstudio.com/
---
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, make sure to follow me on Instagram and
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 100% Free, Frictionless Resume Builder with Direct PDF/Word Exports
Dev.to · Solangi Waqas
How to Deploy Angular SSR on Cloudflare Workers for Free — No VPS, No Fees, No Credit Card.
Medium · JavaScript
How I Added Browser-Based HEIC to JPG Conversion (No Server, No Upload)
Dev.to · Rushikesh Lade
Angular Signals in 2026: From Fundamentals to Architect-Level Patterns
Dev.to · Amanulla Khan
Chapters (11)
Introduction
0:50
What we are starting with
1:37
Using padding instead of gap
3:10
Adding the underline with a pseudo-element
5:12
Adding a basic animation on hover
6:50
Making the line move to the right
9:35
Making the line move to the left
11:28
Cleaning things up with custom properties
12:50
Improving the animation so that it slides
15:50
Browser support for browsers that don’t support :has()
17:05
This isn’t perfect!
🎓
Tutor Explanation
DeepCamp AI