that showcase hover effect is nice! I simplified it a bit: .showcase-list:hover img:not(:hover) { opacity: .5; } that is, instead of :has(img:hover) on the parent selector, just use :hover - simpler and actually looks better, since the whole list of images won't flicker in and out when you hover over the gaps between the items. 💁♂
8:35 for dimming all the images except the one you’re hovering on, I think you can do the first approach with one selector and without using :has. You could just make it .showcase-list:hover img:not(:hover). Pretty similar to the second approach, but still without :has since some people don’t want to use it yet.
The "all previous" and "all after" selectors are useful for calendars, so you can target all days before the one you are hovering (like disabling them or whatever)!
I actually think it's really bad. What if you just happen to need to add a class on there for something unrelated to bullet points? It would instantly fail. I'd rather just have a `.no-bullets` utility class, or something like that and just apply it in the markup. Yes you're writing slightly more code, but it's more verbose, less confusing and you know straight away what it's doing. I think it's a bad use of the attribute selector.
You can start with a :not([class]) to create your own "default" styling for a tag, then add classes to any tags that need different styling. Though you could always use a combination of classes in the same tag to do a much better job of that.
Hey Kevin! I've been following your channel for years and I totally love your content! Recently I experimented with CSS-only performance improvements for rendering large lists, and found out that content-visibility: auto, contain: content and content-intrinsic-size provided the best performance improvements (in that order). I'm planning to write a blog post around it in the future, vut thought that it would also be a good subject for you to cover in your channel.
For the last one, instead of setting the color and background property each time, I would just change the custom property value (e.g. start with -button-color: -clr-neutral-900; then do -button-color: -clr-neutral-100; below).
I had no idea vanilla CSS had nested rules! This feature was one of the reasons I had finally learned SASS for my own projects. I have another tool to use now in my other projects where I can't convince the team to use (read: learn) SASS.
A simple idea to use on 1:18 is a simple start rating system for a product, ecommerce or something. Very handy for the user to rate something from 1-5 for example.
11:28 you could make it so that all the images that aren’t being hovered on fade out and the image that is being hovered on increase in scale as to highlight it.
I prefer using [role="list"] or the nav element to unset the list styles, this keeps semantics. Your class solution feels like a less ideal solution, this require a bit more style to keep semantics.
Actually, relying on presence of class attribute may be a horrible idea if your markup is going to be updated one day by anyone (including yourself). Someone may want to add a class name for any reason and unexpectedly cause a visual bug.
I've gone back and forth on that, but lately have stopped, and only use it if I feel like I *really* need the item to be a list. First, it only removed the semantics for VoiceOver with Safari, and this was done on purpose as many screen reader users prefer when not everything is announced as a list... but VoiceOver also recently-ish changed this too and made it a bit more contextual, like a list in a nav will be announced as a list, even with the list-style: none on it now.
Omg I literally was watching the recent video on select ranges an hour ago! Was trying to select nth-child 3-5. It kept overwriting each other but I think it’s because I was using :is() something like :is( :nth-child(n - 5), :nth-child(n + 3) ) Will have to try again and chain them together instead
I feel like using [class] may introduce some confusion at some later point in the project, making styles seem to "appear out of nowhere". I think it should be used carefully. Do you agree?
It would create a nice effect if the images both after and before were of stepped opacity. Basically creating a fading out effect from the hovered image getting darker the further out it gets.
That would leave you with a situation where when you hover over a gap in the grid then the images are still at 0.5 opacity. Kevin's solution means that the opacity changes only take effect when hovering over an image.
@@edwardgray6167 It felt to me like he wanted to do a one style variant of the first effect but ended up with the flickering, and so added "if it's what you're going for" to justify it 🙂 Just wanted to friendlily point out that the one style variant could also be done without flickering 😉
Honestly. I love nested styles. I used them heavily thanks to lessc (some 10+ years ago). Coming back to webdesign all these years after, I kinda thought that this particular feature would already be supported in all the major browsers. Well. Too bad. :)
We're in the middle of converting our company's web component library to headless components (like tanstack) mainly because of how hard styling is across shadow/light dom with slots/parts. Now we know.
8 месяцев назад
You could make the image you hover larger, and the images on both sides slightly larger, similar to the MacOS dock...
As someone who has been working with it since before css was a thing (so definitely not “starting my journey”), I’ll say that all of those techniques are still much better with single classes . Being more explicit is always better, especially when you are introducing complexity, which you are by creating more complex selectors. Also, descendent selectors introduce coupling, another source of headaches and enemy of readability. TLDR: the techniques are fine, but the underlining advice is not great. On the argument about “old ways” vs “new ways”, some of it will be solved by @scope for instance, so I’m not against change. We simply are not there yet, at a point you should trust the cascade too much.
May I ask why you'd rather nest elements in a list instead of just placing them in the section/nav element directly? I've seen many people do it, but don't understand the exact reason.
And how would you fix this situation? I have a global style for `a{color:#000}` and for `.btn-light{color:#000;background:#eee}`. Now I want a dark footer so I add something like `footer{background:#222;color:#eee}` and also have to fix links so I add `footer a{color:inherit}` but this also breaks my buttons that happen to be used inside footer because now my in the footer has the same color and bg. So now I'm forced to use !important on all my .btn to ensure their colors always fit the background or add more styles specifically to all possible footer elements eg. footer .btn-light{} or have to be more specific on my footer links' selector eg. `footer a:not(.btn):not(.dropdown-item):not(.whatever){color:inherit}`. Is there any easier way to enforce proper styles for such components?
I use custom properties for this. a { color: var(--color-link) } .button { color: var(--color-button); } Then for your various color schemes, you can have a class for each defining the element's colors within them. .theme-dark { background-color: darkcolor; --color-link: somecolor; --color-button: someothercolor; } Then the button and link colors can be defined separately from each other. And if you only ever use the theme classes for color schemes/background colors you can be sure that any content within it will be colored correctly without having to add more styles.
@@Zirpho thanks but I was rather looking for a way to avoid setting additional styles for buttons based on the theme or parent components since it shouldn't matter in this case. Button's color should be only determined by the buttons background, no matter its location on the site. I think @scope could be useful here eg. @scope (.btn-light) {color: #222; background: #eee; }. Though I'm not sure footer a{} won't override it anyway due to higher specificity. Need to do some testing since I've never used @scope before...
Looks like the way to go is "footer :where(a) {}" although it doesn't really work when using class ".main-footer :where(a)" because of a higher specificity (it's actually the same specificity, but because it's after .btn then it overrides it). I think the only way is to force btn's colors in all states with !important 🫤
first tip: interesting, but proned to give $future-me or $other-dev a headache. "WHY IS MY BROWSER GOBBLING UP THE BULLET POINTS. I'M JUST ADDING A CLASS" i hear myself despairing in 6 months. second tip: nice, but why CSS, why!, can't it just be "n >= 7" and "n
Can anyone suggest a channel like this that is solely dedicated to JS vanilla, that helps to explain complex things in a simple way with practical examples. Thanks already.
Love that zindex shirt!!!
How is it that video shows its been uploaded 1 min ago but your comment is 10h old?
channel members can get content early before public release.
We've all done it 😂
Please tell us where to find it
that showcase hover effect is nice! I simplified it a bit:
.showcase-list:hover img:not(:hover) {
opacity: .5;
}
that is, instead of :has(img:hover) on the parent selector, just use :hover - simpler and actually looks better, since the whole list of images won't flicker in and out when you hover over the gaps between the items. 💁♂
8:35 for dimming all the images except the one you’re hovering on, I think you can do the first approach with one selector and without using :has. You could just make it .showcase-list:hover img:not(:hover). Pretty similar to the second approach, but still without :has since some people don’t want to use it yet.
I thought exactly that :) nicely reduce the flickering too
Yes. It’s nothing new as well, that’s a very old trick.
Nice use case for changing something on preceding siblings could be star rating module. Like when you hover on 4th star fill all the preceding stars.
Haha. Just scrolled down to suggest the same. 👍
The "all previous" and "all after" selectors are useful for calendars, so you can target all days before the one you are hovering (like disabling them or whatever)!
That first tip for lists with and without classes is genius
I actually think it's really bad. What if you just happen to need to add a class on there for something unrelated to bullet points? It would instantly fail. I'd rather just have a `.no-bullets` utility class, or something like that and just apply it in the markup. Yes you're writing slightly more code, but it's more verbose, less confusing and you know straight away what it's doing.
I think it's a bad use of the attribute selector.
You can start with a :not([class]) to create your own "default" styling for a tag, then add classes to any tags that need different styling. Though you could always use a combination of classes in the same tag to do a much better job of that.
Hey Kevin! I've been following your channel for years and I totally love your content! Recently I experimented with CSS-only performance improvements for rendering large lists, and found out that content-visibility: auto, contain: content and content-intrinsic-size provided the best performance improvements (in that order).
I'm planning to write a blog post around it in the future, vut thought that it would also be a good subject for you to cover in your channel.
@Le_Sylvestre Sure, will do!
Ive been practicing my css and using the least code possible, it's a challenge I love
I already see the first trick, it's one I can use
.showcase-list:hover img:not(:hover) { opacity: .5; } would have been also worked I think for a single rule approach.
Yes! Came here to say that, but checked other comments first. 😄
I love the reverse nesting idea!! I never even thought about it ! Definitely going to try that one out
As always, another great video! Thanks a lot for the info!
For the last one, instead of setting the color and background property each time, I would just change the custom property value (e.g. start with -button-color: -clr-neutral-900; then do -button-color: -clr-neutral-100; below).
8:30
showcase-list:hover img:not(:hover){
opacity:.5;
}
without the blink when point is on the gap
Thanks!
Thank you so much :D
@@KevinPowell I've learned so much. Just wanted to give back finally.
I had no idea vanilla CSS had nested rules! This feature was one of the reasons I had finally learned SASS for my own projects. I have another tool to use now in my other projects where I can't convince the team to use (read: learn) SASS.
Kudos to your T-Shirt designer. This is hillarious! Love it.
A simple idea to use on 1:18 is a simple start rating system for a product, ecommerce or something. Very handy for the user to rate something from 1-5 for example.
the image grid nth child thing blew my mind
I am working with css more than 2 years now but I wasn't aware that css is this much cool
Thank you for knowledge sharing Kevin.
I watched all your last year videos ...I literally learner a lot...thanks
11:18 An idea: on an image gallery (or a list), when there is a function to change the position of a image (with the precedent or following).
This is exactly the type of video I want. Do these
11:28 you could make it so that all the images that aren’t being hovered on fade out and the image that is being hovered on increase in scale as to highlight it.
I believe this video is one of the most helpful videos you ever did 😊✌
Good ones. Learning something every day. Thanks Kevin!
Dude... had to pause with the ul[class] and just say you can end it here. Dag!
Came here to say THE EXACT SAME THING 😂
Changing styles for preceding siblings could be useful while creating range date picker
I prefer using [role="list"] or the nav element to unset the list styles, this keeps semantics.
Your class solution feels like a less ideal solution, this require a bit more style to keep semantics.
Actually, relying on presence of class attribute may be a horrible idea if your markup is going to be updated one day by anyone (including yourself). Someone may want to add a class name for any reason and unexpectedly cause a visual bug.
I've gone back and forth on that, but lately have stopped, and only use it if I feel like I *really* need the item to be a list.
First, it only removed the semantics for VoiceOver with Safari, and this was done on purpose as many screen reader users prefer when not everything is announced as a list... but VoiceOver also recently-ish changed this too and made it a bit more contextual, like a list in a nav will be announced as a list, even with the list-style: none on it now.
Omg I literally was watching the recent video on select ranges an hour ago! Was trying to select nth-child 3-5. It kept overwriting each other but I think it’s because I was using :is() something like :is( :nth-child(n - 5), :nth-child(n + 3) )
Will have to try again and chain them together instead
Master class as always, thanks!!!!!
nice another learning video , great Kevin, thank you, I'll take notes, when will you make more CSSBattle videos?
I feel like using [class] may introduce some confusion at some later point in the project, making styles seem to "appear out of nowhere". I think it should be used carefully. Do you agree?
It would create a nice effect if the images both after and before were of stepped opacity. Basically creating a fading out effect from the hovered image getting darker the further out it gets.
Interesting CSS moves as always 👍
For the inverse class example, could you not use a selector like `:has(.inverse) .button { ... }` instead?
Kevin powell ❌ Kevin css well✅
We've been using nesting syntax like that in styled components for years
Seems like using the has is a bit overcomplicating things, why not go with ".showcase-list:hover img:not(:hover)" for the second opacity trick 🙂
Definitely could have done that. I was already down the rabbit hole with :has() 😅
That would leave you with a situation where when you hover over a gap in the grid then the images are still at 0.5 opacity. Kevin's solution means that the opacity changes only take effect when hovering over an image.
@@edwardgray6167 It felt to me like he wanted to do a one style variant of the first effect but ended up with the flickering, and so added "if it's what you're going for" to justify it 🙂 Just wanted to friendlily point out that the one style variant could also be done without flickering 😉
Honestly. I love nested styles. I used them heavily thanks to lessc (some 10+ years ago). Coming back to webdesign all these years after, I kinda thought that this particular feature would already be supported in all the major browsers. Well. Too bad. :)
CSS with web-components in shadowDOM makes it all so easy 🤯
Some of the limitations of the shadow DOM drive me nuts though
We're in the middle of converting our company's web component library to headless components (like tanstack) mainly because of how hard styling is across shadow/light dom with slots/parts. Now we know.
You could make the image you hover larger, and the images on both sides slightly larger, similar to the MacOS dock...
Brilliant! Thank you so much.
As someone who has been working with it since before css was a thing (so definitely not “starting my journey”), I’ll say that all of those techniques are still much better with single classes . Being more explicit is always better, especially when you are introducing complexity, which you are by creating more complex selectors. Also, descendent selectors introduce coupling, another source of headaches and enemy of readability.
TLDR: the techniques are fine, but the underlining advice is not great. On the argument about “old ways” vs “new ways”, some of it will be solved by @scope for instance, so I’m not against change. We simply are not there yet, at a point you should trust the cascade too much.
Thank you Kevin!
I am so used to using tailwindcss everyday seeing you write vanilla css looks so difficult i still cant name classes😖
May I ask why you'd rather nest elements in a list instead of just placing them in the section/nav element directly? I've seen many people do it, but don't understand the exact reason.
Plz put a video about dev tools tips and tricks for css
Recorded exactly that this morning 😆 - It'll be out this upcomign Tuesday.
LOVE FROM NEPAL🇳🇵❣️
Why does VS Code say that @layer is not compatible with the major browsers when it clearly is
this is insane)
I feel like such CSS solutions need an obligatory comment, because start to feel like regexes
p.s. saying as a frontend developer
Great Sir 🎉
What’s the font used here?
hi friends, which youtuber teaches javascript so well like how Kevin Powell teaches css?
I need that z-index shirt 😂
And how would you fix this situation? I have a global style for `a{color:#000}` and for `.btn-light{color:#000;background:#eee}`. Now I want a dark footer so I add something like `footer{background:#222;color:#eee}` and also have to fix links so I add `footer a{color:inherit}` but this also breaks my buttons that happen to be used inside footer because now my in the footer has the same color and bg. So now I'm forced to use !important on all my .btn to ensure their colors always fit the background or add more styles specifically to all possible footer elements eg. footer .btn-light{} or have to be more specific on my footer links' selector eg. `footer a:not(.btn):not(.dropdown-item):not(.whatever){color:inherit}`. Is there any easier way to enforce proper styles for such components?
I use custom properties for this.
a {
color: var(--color-link)
}
.button {
color: var(--color-button);
}
Then for your various color schemes, you can have a class for each defining the element's colors within them.
.theme-dark {
background-color: darkcolor;
--color-link: somecolor;
--color-button: someothercolor;
}
Then the button and link colors can be defined separately from each other. And if you only ever use the theme classes for color schemes/background colors you can be sure that any content within it will be colored correctly without having to add more styles.
@@Zirpho thanks but I was rather looking for a way to avoid setting additional styles for buttons based on the theme or parent components since it shouldn't matter in this case. Button's color should be only determined by the buttons background, no matter its location on the site. I think @scope could be useful here eg. @scope (.btn-light) {color: #222; background: #eee; }. Though I'm not sure footer a{} won't override it anyway due to higher specificity. Need to do some testing since I've never used @scope before...
As always Kevin is ahead of me 😀 ruclips.net/user/shorts94qGY28H2cY?si=cDPTlkKib1PvLznc
Looks like the way to go is "footer :where(a) {}" although it doesn't really work when using class ".main-footer :where(a)" because of a higher specificity (it's actually the same specificity, but because it's after .btn then it overrides it). I think the only way is to force btn's colors in all states with !important 🫤
first tip: interesting, but proned to give $future-me or $other-dev a headache. "WHY IS MY BROWSER GOBBLING UP THE BULLET POINTS. I'M JUST ADDING A CLASS" i hear myself despairing in 6 months.
second tip: nice, but why CSS, why!, can't it just be "n >= 7" and "n
Awesome!!!
I starting to really like :has, found out it lets me count- .column:has(> .subcolumn:nth-child(4)) { }.
Review TenoxUI CSS Framework
Love css. Without it website become lifeless but it is underrated, sad truth I think..if disagree someone may reply
The shirt
...
Where do I get one
mal-shop.fourthwall.com/en-cad/products/z-index-9999 😊
Highest shirt in the world!
z-index: 9999; and the host is still halfly hidden 🤯
nice shirt
Can anyone suggest a channel like this that is solely dedicated to JS vanilla, that helps to explain complex things in a simple way with practical examples. Thanks already.
Wes Bos 30 days of Javascript
@@d18517 thanks.
cool shirt
♥️💯
Hear me out: :not(:nth-child(n + 10)) is more readable than :nth-child(-n + 9)
Negative coefficient counters mess up with developers' minds...
круть
Hey Kevin, are you looking for an apprentice? Lol….but seriously?
I am wondering what would he do with you, lol ? 😂 (but seriously?)
Would .showcase-list:hover img:not(:hover) not also work? that would remove the flicker when not hovering any image
Thanks!
Thank you so much!