Creating a CSS-only directionally aware button
Key Takeaways
The video demonstrates how to create a CSS-only directionally aware button using CSS positioning, pseudo-elements, and the :has() pseudo-class, with tools such as VS Code, CSS, and HTML.
Full Transcript
hi there my friend and Friends writing JavaScript to do things that are like styling related has always felt a little bit strange to me there's stuff JavaScript should do but whenever it just comes to styling only then it seems like CSS should be enough to do the job and luckily as CSS is maturing as a language and we're getting a lot of new features there's new stuff that is opening up like creating a button like this one that's directionally aware at least a little bit directionally aware that we can do with basically CSS only there's a few little tricks in getting it done and while we are going to have to leverage a newer CSS feature that actually has better browser support than you probably think it does it also doesn't ruin the experience for people who have an older browser so if you're curious about how we can build that then let's Dive Right into vs code here and I'm assuming the first thing you're going to want to do this is a button I'm not even going to throw a class on here obviously you'll probably have a class maybe it's on a link that looks like a button whatever uh let's just do click me hit save and when we do that we have a big giant button that is right there and that's because I've already added some Styles here just to speed things up there's really nothing fancy that's in here I've just put some padding a background color made the Border radius so it's curved and you know you could do this with any button that you want basically so whatever Styles you want I have a hover and focus visible changing the background on there put whatever starting point you want for your button and it should work there is a little gotcha here though and how this is going to work um which is we're going to add some more stuff here and so I am going to come in here and I never like doing this but we're gonna add a span there and we're going to add a span here um when I first thought of doing this I was going to use pseudo elements but we can't detect hover on pseudo elements specifically um so I wasn't able to work I will admit this is a little bit annoying having to Nest those in there especially if you're just writing like vanilla HTML and CSS if you're using something where you're creating a component it really wouldn't be the end of the world um so it depends on how you're setting things up but if this is a react component or even you know spell faster or whatever it is that you're building out then you'll be fine you just call it fancy button or something and you never have to worry about those bands again but we're gonna leave it like that for now because we're keeping things nice and simple so people can implement this however they want and so yeah we have those two spans there and so we're gonna have to set those up so let's select those I'm just going to do button span so I can select both of them and most of these Styles will apply to both but we'll sort of break things down from there but the first thing we can do let's give them a background we're not going to see them at the beginning but we'll do background uh we'll do orange red because orange Red's kind of a nice color of course they should have a position of app absolute on them I'm going to give them we have the position absolute and actually this is one of those things I didn't put on the main button yet I'm going to add a position relative here we're gonna have a few things we will be adding to this button that are specific for this effect to work but we have the relative that's going to be here and then the absolute on the span and let's give them a width of 33.33 I don't know how many decimals you really need in CSS but that should do the trick for this now we will not be leaving the width like this but we're going to set it like that for now um we could set the height to 100 too just so we actually see them uh and now we actually want to position them in the right places so for that one I'm just going to do button and then do first child now this effect you could actually add a lot more Fidelity to if you had a lot more pieces in here but for a button effect like this I think just having three zones is going to be enough we're gonna have a left Zone a right Zone with the spans and then the middle Zone will just be no span at all uh if you are going to do it with more you'll want to use nth child and like select based on number but we're just going to do first child for this first one and so we can just say a left of zero and a top of zero so it gets positioned right there and then we can duplicate this one right here but choose this one as my last child instead and instead of the left we can do that on the right side and that's basically all we need to do to get those in the right spot uh we'll come back to the span right here and we will do we well we will do a z index and negative one to move it backward but I don't actually want them to be lost completely do we does it matter doesn't uh yeah I think we hmm I'm not sure we will need this for something else though so I'm going to do my isolation of isolate which creates a new stacking context and keeps them from going behind the background of my original button you might be saying Kevin that's a little bit weird because we don't want to see them we are going to change the color of these um I'm going to drop the opacity for now just so they're not so bad but we will eventually be making them completely transparent anyway so you're not going to see them the other thing this makes us realize is right now they're sticking out the sides we will have to turn an overflow hidden onto the button itself but I'm going to do that a little bit later just because it having the Overflow on there is going to help everything make sense um on how it's working and then we'll sort of do the last steps at the end to turn off all of those things so now is the real trick and I actually shared this on the community post earlier and everyone assumed I used pseudo elements I guess because they know me but we're only going to use one of them and it's going to be for what creates that effect right there so we're going to say on the before let's give it a width um the width on this actually it's a before before we do the width we'll give it content so it exists I mean we'll give it a position absolute because we need to be able to move it around and it has to be it like whatever it needs to be absolute so it's out of the flow I'm gonna give this one a background of hot pink so once we start giving it size we'll actually to be able to see it and I'm going to give this a width of 10 I obviously went with like a gigantic font size on here but hopefully by this being a percentage it just means that it would work no matter what size you end up setting things to uh the only thing that's really important with the width here is that it's smaller than the entire button because it's going to make it a lot easier to Center and the reason for that first let's give this an aspect ratio of one which just means the height and width are the same and let's give that a border radius of 50 so it is a circle and I want it to be dead centered inside my button so to be able to do that the easiest thing to do is an inset of zero which means top bottom left and right of zero and a margin of Auto and it's going to go right in the middle if we had our Circle being bigger and then we were trying to do different things to shrink it down that sort of doesn't work but this is just if you're using position absolute or fixed in set zero margin Auto it's centered you don't need that weird translate hack to actually get things to go um always super handy to be able to do that now just like those other you know these transparent things that will be coming that are spans on the edges I should be saying um just like those we do want them to be behind I don't want this to actually cover the text so on here I will also give this a zed index said index of negative one just so it's behind the text itself it's more of a background effect not something that's going to be at the Forefront and now is actually where the magic happens we have everything set up to act create what we need to happen here so what we're going to do is let's do it just so it works out of the middle and then we'll get it working looking for the two sides and so to do that it's actually the easiest one we're just going to say button active and we can choose the before and so when an active means like we're actually clicking on it so this would work on a phone too it's not just a hover effect right um so the active before means when the button is active the before will do something and so when the button is active the before is going to get the scale and we're just going to scale it up so we'll do that as a transform we could do scale as its own property now as well but we'll scale this up and the important thing is that it ends up being big enough because like a lot of the time we do a scale two or something but it's only twice as big so you just want to make sure this is a big enough number and I'm actually going to make it a really big number which might seem a little bit like Overkill maybe we could actually shrink that one down a little bit um and we'll see but maybe we do need the 20 and it's because we need this to actually get really big if we're going to have it work by coming off the two sides as well because right now in the middle obviously it's covering the entire thing but if the circle is growing from here we need it to reach all the way over to that side but before we worry about that let's just come here and do a transition of the before we'll do scale for now so the scale um or not scale transform I should say transform and let's just say 500 milliseconds so we actually have something so we click it grows we let go it shrinks nice and simple right let's change this color now and I already have this color right here again use a color that works for you it's just a dark blue color that I'm using and for now actually let's come and change these spans to be transparent um and I guess we didn't even declare anything on there it would be fine but it's just kind of ugly so now we'll turn them back on um if we need them but when I click it gets really big when I Let Go it gets really small so that's sort of the effect that we're after but obviously we don't want it to explode outside of the button like that so as I mentioned up here we can also come with an overflow of hidden on there and so now when it grows it takes up all the space and then when it goes back down so it already looks kind of cool obviously there's a few other issues we don't want to see it while it's in the middle and everything else but I'm going to leave it there for now um and you know what let's let's just do our background of hot pink for now just because it makes it easier to see what's happening because now we want it to go from the two sides and that's where the I said the magic was happening before this is where the real magic happens by using has so we can say has and then I can choose first child active and this is kind of interesting that it works uh in a sense because even though I'm clicking like here it's the button that's active less so the first child which is that span but hey it works and just to show you it works the background here will turn to red and so if I I click here it's the same if I click on this side and let's turn off the scale change for a sec click here everything looks normal if I click on this side it changes over to red so what that means is we don't actually want to change the button itself what we want to change is the before on that button that has the first child which is active and if you remember I used margin Auto to center it so like there's different ways we can move stuff around my favorite thing to do is to say if it's the first child the margin right left I should say yeah the margin left will be zero and that just means if I click on this side it's moving from there over to here that's all that's going on we'll turn off that scale again to really see I click here it moves to that side because the margin Auto which was centering it is now zero so it moves over to that side now we can take that same thing do the margin right if it's The Lost Child and again this is where if you had more Fidelity you'd have a lot more work to do with like different positioning stuff on this but now if I do that click in the middle it stays in the middle I click on that side and if I click on that side it moves over to the right side because it has a margin left of Auto which pushes things all the way over nice and simple the simpler we can make things the better and then when we scale It Up by click in the middle it grows from there it grows from that side where it grows from that side it's pretty cool now it's not perfect but most of everything you need is here the finishing touches here are just to make sure that when we let go see how it like jumps back to the middle and it always shrinks to there we can't really prevent that with this type of system so what we can do instead of trying to prevent that or maybe you could actually with like transitioning your margin left and having delays on stuff so if you want to try that I don't even know if margin would work to animate it to be honest so anyway we have better ways of fixing this up anyway so the first thing I'm going to do is on this before here we can set the opacity and my CSS here is not very well organized but we can set an opacity of zero uh on the before so now we can't actually see it uh and then I want to click expecting it to show up for some reason uh so when we have the button active we can make the opacity go up to one and so by click in the middle it appears and then disappears still not perfect by any means but it's going to be better now the cool thing with that is it also works on the sides where the opacity will come up because the button is active even if it's the child that's inside of it that we're clicking on um I think what we're going to do now we'll bump this back up to 20. there's a few things here where if we click this way the speed of the animation is actually pretty good when we go on the sides if we go in the middle it's double the speed because of the way it looks I guess uh right where it screws super fast from the middle because of we're getting sort of the side whatever it looks way too fast from the middle whereas from the sides it it looks a little bit better and so what I'm going to do is I'm actually going to take the transition off of there and I'm going to move the transition here and there's an important reason I'm going to do that uh so I'm gonna have the transition here and then what we're gonna do is we're going to select this and we get I mean it's just one line of CSS but I want both of these here and we're gonna have the transition on those as well that would be this one and what we can do now is I can actually make this one longer so I can say this is like a thousand milliseconds so going that way it takes a thousand milliseconds but I go on the sides here it's doing it in half the time and it actually makes it feel a little bit more just like organic in how it's working so we have it growing in that way we have it growing in that way and then we have it coming in that way uh the other thing we could do here is add the opacity in here as well so we can just comma opacity and do that at like 250 just so it like it's we're sort of fading in the opacity a little bit and actually we need the opacity on this one too opacity and for that again we could do it at like double the speed you could set this all up with custom properties you could have one thing that's controlling it um and you update one number and sort of all of these get adjusted based on that number so now if I click in the middle it grows in the middle if I click on the left it goes that way if I click on the right it goes that way it's looking good but obviously when we let go it's kind of weird that it just vanishes it doesn't look fantastic yet so I'm going to take this transition here and I'm going to bring it on to the button before the entire thing and I'm going to drop it here now we're not going to keep everything the same but I'm going to show you what we're going to do and we're going to start with a really slow opacity change just to make it really obvious how this is working so if I do here it looks okay but when I let go it's weird right then it it circles back onto the center so for me the easy fix here is actually delaying the transform animation from happening by the length of the opacity one so for now we'll put a thousand milliseconds um so what now what happens is if I transition or when we transition it's just going to fade out and then so if I do this side and then it just Fades out if I do that side it just Fades out because the transform hasn't come in yet the transform is still exactly where it was at the end so it's not actually scaling down it's staying big and it's dropping the opacity the thing with this is over a thousand milliseconds it still doesn't look good but if we do it very quickly over say 200 milliseconds the problem that's happening now is if I click and it grows and I let go it's still delayed so like if I click on this side it's fine if I let go and then click again it's coming in because that delay we're still it's still counting down that 1000 milliseconds so this is really important that this number and this number do match each other and again maybe a custom property there if you wanted to sort of improve on things a little bit could work so now if I go here it fades that way we can go here we can go there and when we let go it's always fading out the one problem is the color of it being hot pink I don't think looks very good either so now we get it from the middle and of course you can update the timing on all of these if you make it faster make it slower whatever you want lower the opacity of this we can come in at like a 0.25 or something like that this is the space separated syntax where you use a forward slash so it's a little bit more of a subtle effect rather than that in your face one it really depends what you want to do you and you know you can play around with it have some fun with it and use it however you'd like and I did promise to talk about a bit about browser support and basically this is using has uh to function properly but if we didn't have has working in let's just come and put this back up so we can see it a little bit more clearly it's going to go from the middle or grow from the middle or grow from the middle so if you're on a browser that's not currently supporting has then you'd get a little bit of a different experience but it's still going to look cool it just won't be as sort of cool that it's coming off the sides or whatever and you might be saying but Kevin has doesn't have great browser support but guess what uh that's not bad we're only waiting on Firefox really at this point and obviously for some older browsers that it will never be supported in namely in Safari on old iPhones and stuff but it's already past 86 so using it for Progressive enhancement like this I think is a pretty good use case of using something like this where you're not actually rooting the experience of anyone and if this is your first experience in seeing has and you'd like to know more noted and some of the stuff it can do and a bit more to understand how it's really working I have a video right here where I break it all down and look at a few cool examples and with that I would like to thank my enablers of awesome Enrico 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 record on the internet just a little bit more awesome
Original Description
Nothing wrong with a little JS here and there, but it’s always nice when we can make something work without it, and thanks to :has(), there are a lot of new things that are possible with CSS only, like this effect!
🔗 Links
✅ More on has: https://youtu.be/OGJvhpoE8b4
✅ Finished code: https://codepen.io/kevinpowell/pen/dygZEMj
⌚ Timestamps
00:00 - Introduction
00:44 - The HTML and starting CSS
02:20 - Setting up the hover zones
05:00 - Adding a pseudo-element for the effect
06:56 - Making the effect work from the middle
09:20 - Making the effect work from the sides
11:20 - Improving how it looks
14:15 - Improving the look when you let go of the click
16:15 - Browser support
#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 Twitter.
Twitter: https://twitter.com/KevinJPowell
Codepen: https://codepen.io/kevinpowell/
Github: https://github.com/kevin-powell
---
And whatever you do, don't forget to keep on making your corner of the internet just a little bit more awesome!
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
More on: Prompt Craft
View skill →Related Reads
📰
📰
📰
📰
Creta Frontend Interview Experience | Remote Role
Medium · JavaScript
The Case of the Ghost Tooltip
Medium · JavaScript
How I made a scroll-scrubbed video portfolio fast (Next.js 15 + GSAP + canvas)
Dev.to · Pratham Sharma
5 Reasons HTML Is About to Change Frontend Development
Medium · Programming
Chapters (9)
Introduction
0:44
The HTML and starting CSS
2:20
Setting up the hover zones
5:00
Adding a pseudo-element for the effect
6:56
Making the effect work from the middle
9:20
Making the effect work from the sides
11:20
Improving how it looks
14:15
Improving the look when you let go of the click
16:15
Browser support
🎓
Tutor Explanation
DeepCamp AI