How to create a theme switcher with HTML & CSS

  Рет қаралды 109,206

Kevin Powell

Kevin Powell

Күн бұрын

A few custom properties and the :has() selector make color theming super easy to do! Add in a bit of JS and we can save the user’s preferences in localStorage, and we’re good to go!
Of course, :has() support isn’t perfect, but we can build in a quick fallback with just a little bit more JS.
🔗 Links
✅ The code from this video: codepen.io/kevinpowell/pen/MW...
✅ More on visually-hidden: www.scottohara.me/blog/2017/0...
✅ Current support for :has() - caniuse.com/?search=%3Ahas()
⌚ Timestamps
00:00 - Introduction
00:57 - What we’re starting with
01:58 - Setting up the color theme selector
04:04 - Hiding the labels
05:39 - Styling the color theme picker
12:05 - Adding functionality with :has()
13:48 - Using localStorage to remember the users choice
23:52 - Adding a fallback for when there is no :has() support
Corrections:
24:54 I should have made separate selectors here, as this won't work in Firefox - see codepen in description for a working version
27:20 Because I moved this here, the theme should have been changed to activeTheme - see codepen in description for a working version
#css
--
Come hang out with other dev's in my Discord Community
💬 / discord
Keep up to date with everything I'm up to
✉ www.kevinpowell.co/newsletter
Come hang out with me live every Monday on Twitch!
📺 / kevinpowellcss
---
Help support my channel
👨‍🎓 Get a course: www.kevinpowell.co/courses
👕 Buy a shirt: teespring.com/stores/making-t...
💖 Support me on Patreon: / kevinpowell
---
My editor: VS Code - 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 KZfaq channel, make sure to follow me on Instagram and Twitter.
Twitter: / kevinjpowell
Codepen: codepen.io/kevinpowell/
Github: 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!

Пікірлер: 245
@codaniel
@codaniel Жыл бұрын
Don't apologize for the mistake, you fixing it is valuable content! We need more mistakes lol
@szhuravell
@szhuravell Жыл бұрын
Agree. Btw, there are more mistakes to be found)
@nickolaizein7465
@nickolaizein7465 Жыл бұрын
All I know and all I have is reached on mistakes :)
@keithanphilander3251
@keithanphilander3251 Жыл бұрын
I was going to say the same thing. I love seeing that even advanced CSS developers sometimes make mistakes. We're all human and it gives someone like me that little bit of hope. Like, hey maybe I can actually do this.
@kyrill19
@kyrill19 Жыл бұрын
Indeed Cryptologic. Mistakes=life and life=mistakes. I even love it that Kevin admitted it right away
@mcELINER
@mcELINER Жыл бұрын
I rather have an hour long video where you dissect every step of your thought process (mistakes included), than have a 10 min video only showing how it's done and then I spend 4hours trying to figure out how to implement MY version of it :D
@mayukhdevansahu5707
@mayukhdevansahu5707 Жыл бұрын
I just love how Kevin always makes sure to include accessibility features to his website for visually impaired persons. In general, it's very rare in tutorials where you see things like that.
@hollengrhen1
@hollengrhen1 Жыл бұрын
I like how the mistake are fixed raw like without editing or trimming the video or even adding annotations. Thanks for that, Kevin
@EvanEdwards
@EvanEdwards Жыл бұрын
A better event than 'click' may be 'input', as _somebody_ is going to tab and enter on those radio buttons and bypass your event handler. I ran into that earlier this year in similar code.
@RodrigoMendoza7
@RodrigoMendoza7 Жыл бұрын
Another improvement is Event Delegation. Instead of listening for the click event for each input, the event could be attached to the document, therefore, it's attached only once. Then you'd apply whatever you need in case an input was clicked.
@Lernschau
@Lernschau Жыл бұрын
@@RodrigoMendoza7 I agree on the concept of event delegation, but there is no one fit solution for everything and this type of general delegation seems pretty inefficient to me on the long run. On any average page these days there's much more happening than clicking on a radio button. Going "as far up" to the document wouldn't and shouldn't *always* be necessary. That form would do very well as the "delegate" and in case of "click" should probably also cancel the event from bubbling up, causing any other handlers to run for no good, possibly wasting time and memory. For *many* situations it's usually fine to just delegate the task to the next logical parent element ("component level") like the form in this case, and don't bother the rest of the code making logical decisions that could've been done with much earlier. If you attach all your same event type handlers only on the document (body) you'd eventually end up calling handlers that don't actually apply and test for the event target (DOM access) or some condition many times only to discard them most of the time.
@KonRud5
@KonRud5 Жыл бұрын
Nice one. A tiny note though. In your JS file `document.onload = setTheme()` this expression does not exactly do what you expect it to. When your page loads your JS file runs and when it comes to line 25 `setTheme()` function runs (retrieves data from localStorage, checks one of the radio buttons, etc...) and assigns `undefined` to the `document.onload`. Hence `onload` event doesn't really run at all. Moreover, for this type of action, you could probably use `DomContentLoaded` event. The DOMContentLoaded event fires when the HTML document has been completely parsed, and all deferred scripts ( and ) have downloaded and executed. It doesn't wait for other things like images, subframes, and async scripts to finish loading.
@Seki952
@Seki952 Жыл бұрын
Very well put. Thanks!
@AntiAtheismIsUnstoppable
@AntiAtheismIsUnstoppable Жыл бұрын
Also, I would place the event handler (just one) on the form and use event delegation instead of one event on each button. This is because having too many event handlers is very costly and it will eat your battery like nothing else. People on phone will hate you if you do not do event handling correctly.
@SvenThielen
@SvenThielen Жыл бұрын
I tried the codepen link given by Kevin and in firefox which doesn't support the has css tag, it doesn't work. So like you said, the JS portion doesn't do what is expected. I however don't understand what to modify to use DOMContentLoaded from your remark. Do you have an example?
@KonRud5
@KonRud5 Жыл бұрын
@@SvenThielen It won't work in FF because CSS declarations that define theme styles are invalidated due to the fact FF doesn't support `:has`. That is, // When parser is trying to parse this declaration it invalidates it because it has an invalid (for the FF parser) selector (i.e. :has) .blue, :root:has(#blue:checked) {.... } If you want it to get to work in FF you first need to remove `:has` selectors (e.g. .pink {...} instead of .pink, :root:has(#blue:checked) {...}). Moreover, when you check radio buttons, there is no code in JS file which handles it. As for DOMContentLoaded what I meant was rewriting it in the following manner `document.addEventListener("DOMContentLoaded", setTheme)` Hope this helps.
@eruryuzaki6505
@eruryuzaki6505 Жыл бұрын
@@AntiAtheismIsUnstoppable Optimising performance for 5 click handlers which are triggered on average once per visit is a wasted effort. The greatest "performance hit" in Kevins implementation if any is actually the document.querySelectorAll because it is a linear search trough the whole DOM. Would this concern you? I hope not. JavaScript is blazing fast these days. So no. Five click handlers will not "eat your users battery". What's more dangerous is mouse-move and scroll event handlers because they are triggered up to once per frame.
@Mr.RobotHead
@Mr.RobotHead Жыл бұрын
I used a very similar method when experimenting with themes before having ":has". The way I handled the styling flash is that I started with all color vars being black and setting a transition. So, the page starts totally black and fades to the selected color scheme.
@JoeGelman
@JoeGelman Жыл бұрын
smart!
@NotKyleChicago
@NotKyleChicago 7 күн бұрын
Where did you put the transition "stuff"? I'm guessing it was in the body part of the CSS to ensure it was not duplicated in each specific theme.
@k3tna
@k3tna Жыл бұрын
Kevin, thank you. It's mad how easy everything is when you explain it.
@kyrill19
@kyrill19 Жыл бұрын
This is incredible Kevin, thank you so much. I just watched it through in 1 go. And I will watch it again slower to exactly implement the Code and try it myself. I really love your channel and videos. Just now I shared your channel with me co-workers cause at least 3-5 of us are all working, studying and learning about CSS :)
@KB-kj6dj
@KB-kj6dj Жыл бұрын
Dude, you're awesome and spreading the wealth. WE APPRECIATE IT. I never comment, like once in 5 years kinda never. You deserve the praise. Thank you.
@funlandhq
@funlandhq Жыл бұрын
The best tutorials i'm watching right now. Thank you so much!
@holger3526
@holger3526 Жыл бұрын
Amazing footage in short (as always)!
@AquaRedX
@AquaRedX Жыл бұрын
I remember making my website using languages instead of color themes for Portfolio website when learning html, css. This is an amazing process to go through and learn. Awesome that we have this on YT. I learned it googling and searching and stealing websites sooo much to understand the process.
@lukedharrison326
@lukedharrison326 Жыл бұрын
That custom radio solution is genius Kevin!
@LeviSkaggs
@LeviSkaggs Жыл бұрын
Awesome! Thanks for continuing to put out amazing content!
@javascriptes
@javascriptes Жыл бұрын
This is fantastic Kevin! 🎉 The :has property is amazing. I will teach this to my hispanic audience 😊
@JoeGelman
@JoeGelman Жыл бұрын
Kevin, you are a true maestro!
@jeetrana3447
@jeetrana3447 Жыл бұрын
I was just looking for this few days ago thank you for uploading this video!
@EnzoAuditore
@EnzoAuditore 2 ай бұрын
So many things i had no idea existed. Thank you for this
@tranthanhlan1685
@tranthanhlan1685 Жыл бұрын
This king completes people's skills. Respect.
@crvlwanek
@crvlwanek Жыл бұрын
Would be cool to also incorporate prefers-color-scheme since a lot of devices (phones in particular) now allow the user to specify their preference
@junihh
@junihh Жыл бұрын
Just saying: Instead of use forEach after retrieving the color for set the input radio, you can do document.querySelector(`input[type="radio"]#${activeTheme}]`).click(). 🍺
@yuriykolomytsyn2352
@yuriykolomytsyn2352 Жыл бұрын
Thank you so much for sharing this great experience with us :) have a productive day
@mashroorzisan
@mashroorzisan Жыл бұрын
So humble man...How he is apologizing for one mistake!❤❤
@TobbeLund
@TobbeLund Жыл бұрын
Fantastic tutorial!
@iamshawnalways
@iamshawnalways Жыл бұрын
Good luck Kevin. I referred your channel to my interns. You have wonderful contents. Big thumbs up for your effort 🤜🤛
@_nikeee
@_nikeee Жыл бұрын
IIRC, if the browser does not support a selector in a list of selectors (like .green, root:has()), it drops the entire rule. I think you can use :is() to fix that. Because that's not done in the video, the theme selector actually should not work when the browser doesn't have :has(), even with the presumable fallback.
@jayasood3205
@jayasood3205 Жыл бұрын
Awesome video as always!!!
@nae19701114
@nae19701114 Жыл бұрын
Awesome! Thank you for share this!!
@enio.carlos
@enio.carlos Жыл бұрын
Amazing Tutorial.
@BossPetta
@BossPetta Жыл бұрын
Great again Kevin! 😎 :has... I can't wait for all browsers to fully implement it.
@treeteqs
@treeteqs Жыл бұрын
Amazing, you're the best, thank you so much for your efforts
@AbhinavKulshreshtha
@AbhinavKulshreshtha Жыл бұрын
Loved this video, I basically gave up on having multiple themes years ago. These days, I just do a dark and light theme and set it based on prefers-color-scheme media queries. This video gave me a new hope. I wish firefox gets a better ceo, I want them back working on improving servo, and implement new stuff under the hood, not the stupid colorway experiment and ui tweaks.. :has selector is amazing addition to css and my fav browser is lagging behind.
@nimbus321
@nimbus321 Жыл бұрын
Wow this is the first time that I notice a mistake from you first, I was really confused about it but I let it go, I was happy when you corrected it and the mistake was not mine 😅
@collinsk8754
@collinsk8754 Жыл бұрын
Great tutorial! 👍👍
@ThomKnepper
@ThomKnepper Жыл бұрын
This is awesome! I am going to use this for some websites!
@haliszekeriyaozkok4851
@haliszekeriyaozkok4851 Жыл бұрын
It's good to watch which css king could write js code and we can learn methods we don't know before 🙂
@thecodegod2434
@thecodegod2434 Жыл бұрын
Amazing Content Always. Thanx Kevin
@tithos
@tithos Жыл бұрын
Thank you for demystifying this topic! I have implemented theme systems before, but they were WAY over engineered. 😃
@clevermissfox
@clevermissfox 5 ай бұрын
I'm thrilled that if I have an ID on something I don't have to add a class to style it, I just use the attribute selector so specificity is the same but no extra class if not needed! [id=pink]. Felt really clever 😂
@nv3796
@nv3796 Жыл бұрын
wow... such a helpful content !
@jimmytan6543
@jimmytan6543 Жыл бұрын
Thanks for the video!
@privuspriv
@privuspriv Жыл бұрын
thanks for sharing this knowledge
@TheMediinaa
@TheMediinaa Жыл бұрын
Thanks! You absolutely made me love css a bit today, it's exactly what I've been trying to figure out the past few days (in the end all I needed was to know :has in css). Here is my token of gratitude (it's not gonna be a lot because of my currency, sry about that 😅)
@KevinPowell
@KevinPowell Жыл бұрын
Thanks so much!
@davidarnold1881
@davidarnold1881 Жыл бұрын
Really excellent tutorial. Great minimal landing page a11y friendly and performant
@UsernameUsername0000
@UsernameUsername0000 Ай бұрын
Just a JS note, the thing you assign to document.onLoad should be a function (reference). Your code has a slight problem on this line `document.onLoad = retrieveTheme()`; you’re invoking the retrieveTheme function and then setting `document.onLoad` to undefined (since that’s the return value of `retrieveTheme()`). The app works just fine since you’re invoking `retrieveTheme` regardless, but not in the way you probably intended. The correct version should just be `document.onLoad = retrieveTheme`. This way, you’re giving `onLoad` the function reference, and >IT< gets to decide when to invoke that function instead of you prematurely invoking it. Just thought to draw your attention to it. Fantastic work!! :)
@cloudsystem3740
@cloudsystem3740 Жыл бұрын
Thank you very much i would love to see you doing some more javascript concepts implemented with css!👍
@dave-7117
@dave-7117 Жыл бұрын
When using js you can get rid of the flickering by using a script tag in the head. Vite does it on their docs site, it´s pretty easy :)
@EpicNicknameFail
@EpicNicknameFail Жыл бұрын
Really cool !!
@rebelshadowrm
@rebelshadowrm Жыл бұрын
You forgot to add that fallback code to the storeTheme function as well. Without Has support you'd need to refresh the page to see the theme change. Either way, always a big fan of your videos, good work.
@itsdonnix
@itsdonnix Жыл бұрын
Another great tutorial! 👌🏼 To fix the flash, using 'DOMContentLoaded' event instead of 'load' or put the script as inline script after the color picker element.
@sogggy
@sogggy Жыл бұрын
Here before Web Dev Simplified.
@speedstyle.
@speedstyle. Жыл бұрын
If you put the JS after the form, you can set the --vars immediately/synchronously rather than in the onload, avoiding the 'FOUC'. Or if your server isnt static you can put it in a cookie, and respond with the right theme in the header
@SlickStatus
@SlickStatus Жыл бұрын
Nice explanation sir something new........
@El_Traficante
@El_Traficante Жыл бұрын
Funny thing is how I've learned so much more about HTML watching your presentations than by doing the same with some videos explaining it. And you focus on CSS. All the best!
@i.j.5513
@i.j.5513 Жыл бұрын
For getting rid of that flicker of the checked state in the beginning, you could also set the body or the theme switcher's opacity to be 0, then set it to 1 (or add the appropriate show class to it) in setTheme(), along with a short opacity transition.
@toxicsnails
@toxicsnails Жыл бұрын
Or remove the `checked` attribute from the HTML. In the JS, you could set light to `checked` if no theme found in localStorage, but removing the hard-coded HTML attribute will remove the flicker.
@i.j.5513
@i.j.5513 Жыл бұрын
@@toxicsnails Even better! 👍
@veluk88
@veluk88 Жыл бұрын
With flickering problem: You could probably solve it with few more lines of js. First, don't set default radio value. Call retrieveTheme. If there is theme saved in storage, set it, if not set default radio checked (light). Just a wild guess :) Nice :has solution.
@piotr-nowak
@piotr-nowak Жыл бұрын
very nice!
@dominikawojewska3985
@dominikawojewska3985 10 ай бұрын
What a fantastic tutorial! I learned so much and finally understood :has() a tiny bit better. However, when I'm trying it out in does work perfectly in Chrome but not at all in Firefox, even with the fallback :( I tried playing around with it to make it work in Firefox, but it just doesn't want to...
@frankcastle3288
@frankcastle3288 2 ай бұрын
Great one! thiny thing (probably mentioned already) in your final fallback for no-has you set the html class to the variable theme but it should be activeTheme. Also, you need a default in casse there is nothing in localStorage, I guess.
@briankgarland
@briankgarland Жыл бұрын
Excellent!
@danyEl_M
@danyEl_M Жыл бұрын
Thanks
@GuruKuen
@GuruKuen Жыл бұрын
Using cookies as opposed to localstorage could be a way around the window.onload issue. This would of course require the back-end renderer to do some of the job. But it doesn't have to be more than setting the initial html class or checking the correct select option.
@JJ-rv7tt
@JJ-rv7tt Жыл бұрын
11:28 Using the outline instead of the border creates here an accessibility issue, in that the focus ring is no longer visible on the element To get around this you could change the appearance of the outline during :focus-visible
@godnyx117
@godnyx117 Жыл бұрын
Thank you!
@stefanosilvestri89
@stefanosilvestri89 Жыл бұрын
beautiful stuff! thank you kevin!💪 one thing: on line 16 of the js you should have '= activeTheme' not '= theme'.
@godnyx117
@godnyx117 Жыл бұрын
+1!
@AdarshSingh-qd6mq
@AdarshSingh-qd6mq Жыл бұрын
Good One...
@PicSta
@PicSta Жыл бұрын
Great video Kevin, I think the only improvement will be the console error in line 16 as it says undefined theme. I used double quotes around "theme"
@GagikHarutyunyan_dev
@GagikHarutyunyan_dev Жыл бұрын
to solve the problem with jumping, you can remove the default checked property inside html, then add else {} block, and if(...) {...} else { colorThemes[0].checked = true }
@DrawdeThePotato
@DrawdeThePotato Жыл бұрын
Thanks for the video!!! Can you use the LAYERS panel in chrome inspection tool so we can visualize the changes in 3d so we can better understanda where everything is in relation to the screen. I thing it would look awesome if it appear when you are adding or modifying the css we have another perspective to how is implemented on the page. You can probably just put the LAYERS on another screen and record that screen separately.
@ElectricKota
@ElectricKota Жыл бұрын
You can actually leverage :checked status of radios with the variables and don’t use :has at all, it work for me on every browser, and I am using it even for every mobile menu, buttons that open some containers and so on without JS.
@faguolvlv
@faguolvlv Жыл бұрын
Kind of did the same on the calc app on frontend mentor. Used a input range and a data attribute on the body to store the theme. Then override my variables in the css. Only probleme is styling the input range not really supported lol.
@CZghost
@CZghost Жыл бұрын
Another way to store the theme selection would be through the use of cookies, but that's beyond the scope of HTML/CSS, it's more of a backend solution, but that will get rid of the flashing.
@grantpeterson2524
@grantpeterson2524 Жыл бұрын
Hello! Thanks for posting this helpful video. I'm trying out web development after coming from Python, C#, and C++, and was wondering why you are defining functions by storing an anonymous function as a constant? Is this considered more idiomatic in javascript than function foo(bar) {} ?
@chrisbolson
@chrisbolson Жыл бұрын
Another great tutorial, thanks. As far as I can tell f the browser doesn't support :has() I am not sure that, with your code, clicking on the radio buttons will actually change the theme until the page is reloaded. This can of course be overcome by adding more JavaScript or am I missing something?
@joaomarcelo4940
@joaomarcelo4940 4 ай бұрын
this is so f cool
@drsensor
@drsensor Жыл бұрын
Firefox actually has theme/css switch baked in that even documented in the MDN. But alas, it didn't make it to the WICG standard.
@Lernschau
@Lernschau Жыл бұрын
yeah, and it does so since version 1!! And meanwhile they hid it in the classic menu bar (View -> Page Style) so many users won't be able to find it anyway... It's sad no other vendors picked this up. All you need is set a title attribute on your link element and off you go and pick that style from the Page Style submenu.
@bumbleguppy
@bumbleguppy 7 ай бұрын
You COULD have the inputs without any containers just floating between body and main and only apply the colors to the main element with input#pink:checked ~ main. As long as main is full screen I guess.
@user-br9tr5xn3y
@user-br9tr5xn3y 5 ай бұрын
wow ! you're just a Jedi
@RaveKev
@RaveKev Жыл бұрын
Wow, that's such a cool "hack"!
@KevinPowell
@KevinPowell Жыл бұрын
Thanks so much!
@radenmulyadi2589
@radenmulyadi2589 Жыл бұрын
thankyou for appearance:none. I learns many things from your videos
@arkemiffo
@arkemiffo Жыл бұрын
Really cool video. Just a question regarding the Javascript. Where you set the option to checked, why loop through them, since the element id is the same as the stored themename, you should be able to just do a "document.getElementById(activeTheme).checked = true" shouldn't you? That should remove an unnecessary loop, and a conditional. Not that it matter much, considering the small amount of items to loop through, but I'm always trying to see where I can skip loops or conditionals, and I think you can do that here.
@metalstarver642
@metalstarver642 Жыл бұрын
Need to make sure element exists, to prevent exception in case in future IDs are changed or someone messes up with localstorage.
@arkemiffo
@arkemiffo Жыл бұрын
@@metalstarver642 Ah, yeah. Very true. Still though, I'd rather use the conditional to check that than use a loop, but it's most likely just personal preference.
@9990490677
@9990490677 Жыл бұрын
To add to your point, we can use event delegation and listen to one form listener instead of managing individual listeners.
@arkemiffo
@arkemiffo Жыл бұрын
@@9990490677 I was thinking along those lines as well, but you'd need to get the selected radiobutton somehow, which would mean a loop through the forms children at each event instead of one loop at the initialization of the form. But then again, maybe we could get that radiobutton from the event.target. Not sure what element would be passed along here.
@Italiafani
@Italiafani Жыл бұрын
@@arkemiffo If one used the `value` attribute with the radio buttons, one could get the current selected theme using the FormData API. form.addEventListener('change', () => { storeTheme(new FormData(form).get('theme')) }) Then you could also `check` the stored theme like this: const theme = localStorage.getItem('theme') if (theme) { form.querySelector(`[value="${theme}"]`)?.checked = true } Note the `?` added to meet @MetalStarver's test case.
@farhan-app
@farhan-app Жыл бұрын
This is such a powerful tutorial - you can do so much using a checked state beyond setting colour profiles/themes. Thank you very much! If there is a way we can directly contribute to your efforts such as paypal, please let us know!!!
@Lernschau
@Lernschau Жыл бұрын
ways to contribute are mentioned in every video description
@farhan-app
@farhan-app Жыл бұрын
@@Lernschau I know, but I’d rather contribute directly to Kevin than through something else because they would take a %% :)
@Lernschau
@Lernschau Жыл бұрын
@@farhan-app well Paypal (as you suggested) also takes a %% fee, so what's your point exactly? ;-) He apparently seems fine with Patreon, and he's running a business, so he can't just accept "donations" from any arbitrary source :D
@farhan-app
@farhan-app Жыл бұрын
@@Lernschau Not if I send $$ to a "friend"
@shalevtamir
@shalevtamir Жыл бұрын
Great tutorial ! A little question: if you don't click on any theme when you first open the page then the value for the key 'theme' wouldn't be set to anything and the key 'theme' would be undefined since it is only being defined on the onclick event wouldn't this throw an exception when trying to retrieve the value?
@tesilab994
@tesilab994 2 ай бұрын
localStorage.getItem('theme') will simply return null, which in his example simply will not match any of the radio button ids, and so have no effect. If he were just to apply it to an element by id, he'd have to test the result for null, or test the result of his search for an element with a null id before applying the theme.
@potrosanjuan
@potrosanjuan Жыл бұрын
Hi Kevin, great video as always. I just have a question. Wouldn't it be better if you didn't set the first option as checked and only do it if there's no theme in the localstorage?? This way I think there wouldn't be that small jump on the load.
@KevinPowell
@KevinPowell Жыл бұрын
I think it would still flicker, since we need the page to load and for it to pick one of them to be checked anyway. Worth testing out tho
@narcos1024
@narcos1024 Жыл бұрын
@@KevinPowell is it possible to run this specific JavaScript before the html and CSS? The page load would be a bit slower but no flicker. Just guessing. :)
@jesseajioh4111
@jesseajioh4111 Жыл бұрын
@@narcos1024 You're right. I think to prevent the page from flickering, you'll have to write the JavaScript code for retrieving and setting the theme inside of the html document itself. This will block rendering of the html body until the theme has been set.
@biggand8520
@biggand8520 Жыл бұрын
Hi Kevin. Why don’t you use just accent color and transform to make them bigger?
@upasanaasopa6406
@upasanaasopa6406 Жыл бұрын
Hey Kevin can you please show responsive navigation with sun menu, as am really struggling with that please
@ImIvee
@ImIvee Жыл бұрын
I don't want to be "that guy", but the 'theme' in the line 16 should be 'activeTheme', so the last run of the code worked because of the :has() pseudo-class 😅 Nice video tho, already want to try this approach to theming :)
@Lernschau
@Lernschau Жыл бұрын
don't worry :) Kevin did notice and added an errata in the video description. The correct code is in the codepen for this video.
@pruchay
@pruchay 2 ай бұрын
Thank you for this video. I have a question. This approach Is good, then I have predefined themes. But what if I want to add the ability for users to create their themes? What approach should I use in this case? Themes will be dynamic, created by users, and stored in a database. So I can't create a list of colors in a CSS file.
@lookupverazhou8599
@lookupverazhou8599 Жыл бұрын
Prooooo!
@SmileyFaceEmoticon01
@SmileyFaceEmoticon01 Жыл бұрын
Hello I really enjoyed the video and tested it out chrome and it seemed to work. I tried testing this on firefox but recently found out that :has() isn't compatible with firefox because of DOM issues and that doesn't seem like its going to be fixed soon. I believe the reason is that :has() doesn't work on html generated by javascript. Is there another way to do this without the :has()? With or without javascript?
@brentspotswood
@brentspotswood Жыл бұрын
Fix the load flicker by just dropping a script tag in the HTML that fetches the theme and sets it to the document class name before loading the rest of the HTML elements. document.documentElement.className = localStorage.getItem("theme");
@Lernschau
@Lernschau Жыл бұрын
crude but effective :) However, you should add some default value if the item wasn't set before localStorage.getItem("theme") || "dark";
@umairalibhutto3416
@umairalibhutto3416 Жыл бұрын
no link for the code from this video by the way love the work and effort you put in the video
@natescode
@natescode Жыл бұрын
It's Jabba script with that shirt 😊
@iamenochlee
@iamenochlee Жыл бұрын
Hey Kevin when setting the fallback for :has you should be adding the class activeTheme not theme, Great content as always
@KevinPowell
@KevinPowell Жыл бұрын
Err, yeah. I think the :has() support was making it work anyway and I didn't notice. Fixed it in the linked code and I'll add a note, thanks!
@ancwhor
@ancwhor Жыл бұрын
Big brain
@digeshbajracharya3225
@digeshbajracharya3225 Жыл бұрын
does :has work perfectly fine with container queries?
@GR_BackingTracks
@GR_BackingTracks Жыл бұрын
Oh, Lord Algorithm has popped this into my paws right on time...
@mbguantay
@mbguantay 2 ай бұрын
is it possible to change the background of the html just using css3 without using js? Thank you very much for your awesome video
@RuneScapeZammy
@RuneScapeZammy Жыл бұрын
Hi Kevin! The problem of the theme flickering on page load sparked an idea... I wondered if you can set a transition on custom properties themselfs. I tried it and unsurprisingly it doesn't work. You'd have to have the transition on the property you're applying the custom property to. Whats your oppinion? would you like to be able to put transitions directly on custom properties? Maybe via @property. Do you know of any active proposal regarding this?
@KevinPowell
@KevinPowell Жыл бұрын
I think you could do it, but I'm not sure if it could cause some performance issues of everything was changing at once or not
@forbiddenera
@forbiddenera Жыл бұрын
was hoping for some @media (prefers-color-scheme: dark/light) action. Can't figure out a good way to not have to repeat the defs within the media; one can use js to modify the css (doc.docEl.styles) directly and swap the definition for each light/dark color set (ie prefers dark becomes prefers light vice versa) which is valid except if you want to SSR a saved theme (cookie) because then you also need it available in a class to apply to :root (html) or body since even ff which is supposedly (mdn) supposed to obey parents color-scheme property doesn't seem to do so for :root/html so you can't just have :root.dark { color-scheme: dark; } as an override?
@Lernschau
@Lernschau Жыл бұрын
Maybe you don't need js at all. The link element supports a media attribute since ever, so you can create two separate stylesheets for each theme and let the browser decide upfront which one to download and apply. The other file download will be postponed and cached only used should the user actually switches theme. Having two individual files also simplifies keeping themin sync, wheres several @media in a single file are not only wasteful for users using the "other theme", is also makes things more complicated to keep all variables in sync. If you need JS for more conditions, the following article may also give you some ideas using the media attribute - filamentgroup.com/lab/load-css-simpler/ - based on their loadCSS project on Github. Enjoy.
@JerkerMontelius
@JerkerMontelius Жыл бұрын
Good work but teach us how to remove that first annoying color shift.
@mikinitsunoru8211
@mikinitsunoru8211 Жыл бұрын
Is it possible to use this kind of button to make language switchers?
Learn flexbox the easy way
34:04
Kevin Powell
Рет қаралды 685 М.
Relative colors make so many things easier!
13:16
Kevin Powell
Рет қаралды 20 М.
Я нашел кто меня пранкует!
00:51
Аришнев
Рет қаралды 2,8 МЛН
孩子多的烦恼?#火影忍者 #家庭 #佐助
00:31
火影忍者一家
Рет қаралды 40 МЛН
Жайдарман | Туған күн 2024 | Алматы
2:22:55
Jaidarman OFFICIAL / JCI
Рет қаралды 1,5 МЛН
OMG🤪 #tiktok #shorts #potapova_blog
00:50
Potapova_blog
Рет қаралды 18 МЛН
Create an animated pop-out effect // HTML & CSS
19:49
Kevin Powell
Рет қаралды 69 М.
Subtle, yet Beautiful Scroll Animations
5:04
Beyond Fireship
Рет қаралды 1,6 МЛН
Avoid these 5 beginner CSS mistakes
21:38
Kevin Powell
Рет қаралды 74 М.
A deep dive into CSS color-mix()
18:06
Kevin Powell
Рет қаралды 25 М.
Learn how to power-up your CSS with PostCSS
20:23
Kevin Powell
Рет қаралды 81 М.
Responsive CSS Will Never Be The Same
12:08
Web Dev Simplified
Рет қаралды 265 М.
How to take control of Flexbox
16:01
Kevin Powell
Рет қаралды 116 М.
This Is So Much More Than Just A Parent Selector
12:44
Web Dev Simplified
Рет қаралды 43 М.
Cloning Google Font's Light/Dark Mode Toggle
51:34
Kevin Powell
Рет қаралды 78 М.
Я нашел кто меня пранкует!
00:51
Аришнев
Рет қаралды 2,8 МЛН