Probably one of the best videos explaining the problem, a solution that doesn't work and explain why, then go on to present a better solution. This is quite rare in tech videos, which often skip over the why's and hows. Kudos!
Thank you, I appreciate this comment that balances the "get to the point, you wasted 10 minutes!" comments. Glad you enjoyed the progressive explanation - I wanted the message to land properly.
Thanks for explaining the problem. I ran into this when updating tailwind, all of a sudden everything looked wonky. I looked into twmerge but felt like it was a hassle to update the whole codebase to call a utility function. Feels like something that should be solved at compile time.
Hey Simon, would you please consider using dark mode? The white screen flashbang is really hard in the eyes, especially at night, and I mean hard as in squinting my eyes and then giving up on the video. Love your content and I hope you give this some thought.
Thanks for the suggestion. I struggle with the opposite with my eyes, but you make a good point. I usually use Night Owl Dark and no one ever asked for light - so I'll do the next video in dark theme!
Never thought the opposite was algo possible! It makes sense. But yes, flashbangs are something that always gets comments throughout UA-cam, and some UA-camrs even warn before one happens. Keep up the good work bud, and I'd love to hear your take on tailwind and toast notifications solutions like react-hot-toast that don't make it necessarily trivial to integrate with it.
You shouldn't watch anything in darkness anyway. That's bad for your eyes, like really bad. You should always have some kind of light. I am coding just fine with a light theme at 3am. Why? Because I have the fricking lights on.
9:52 You've been waiting for THIS part for almost 10 minutes. The thing is that this library opens the gateway to tailwindized component libraries all over the place. You will finally be able to Bootstrap + Tailwind with no issues (I guess)
Thanks Simon for recording this video and explaining the why. What would you recommend doing in situations where I’d like to allow the users of to override certain classes (e.g. ) but restrict (or, at least warn) users from overriding other classes (e.g. )?
Thanks! In that scenario I think it makes sense to setup a few style props for spacing, width etc instead. Sort of how Theme UI or Shakra UI work, if you are familiar with them. Or a "layoutClasses" prop that only allows "contextual" classes (width, margin, display etc). Might be a bit confusing for the user though 😅
1. U can add jsdoc to the `className` prop, and tell users about ur intention 2. U can add, for dev mod only, runtime checks and logs. This can be a little bit complicated bcs u need to cover custom matching (or maybe there is already a solution idk)
That's pretty cool. I've never had that issue, didn't even know that was a thing. But now that I stop for a second and think about it, it seems obvious. And also, I wonder why I've never seen this issue, since it seems like I should have. Although I might have hacked a workaround to something just like it the other day!
@@simonswiss Maybe. I also tend to handle situations like your example by defining a "theme" property on the button, then handling the selection of classes entirely within the component rather than passing classes in. So I've probably mostly avoided it using different design patterns.
Yep, what you describe (style variants via props) is definitely the way to handle various styles.. but even then, I had accidentally a sneaky conflicting padding classes combo when having 4-5 composable style variants, even trying to be careful with separating styling concerns between 'size', 'look' 'shape' etc. Can indeed be avoided but sometimes it becomes quite involved with multi-style variants.
@@simonswiss Yeah, padding was one I was specifically thinking of. The number of times I must have mixed sm:p-, p-, px- and pl- or pr- together on the same div and seem to have gotten away with it. Granted some of those will be different CSS properties, so CSS would presumably resolve that conflict internally. There's a few times, I've found myself thinking "The class is at the end, so it must be winning". which as you pointed out in the video is actually CSS order, not class order. So I feel like I must have been down this rabbit hole without recognising it, then hacked my way out without really understanding what I'm doing.
`tailwind-merge` also supports custom conflicting class names. let's say we have custom class names that should conflict if we pass it together, e.g `alert-success`, `alert-error`, `alert-info` if you use normal/default `twMerge`, it can't detect the conflict because `alert-success`, `alert-error`, `alert-info` is not supported by tailwindcss by default. but we can use `extendTailwindMerge` or `createTailwindMerge` and define our custom conflicting class names pretty neat
Thanks Simon, can we have a video on how to make reusable components with Tailwind ?, Where UI can be customized using props. Similar to how MUI and other component libraries work.
It's not free, but I have a Pro Tailwind workshop on exactly that, which I think you'd like: protailwind.com/workshops/multi-style-tailwind-components I also have a free article covering _some_ of the contents, you might start with that :) www.protailwind.com/just-in-time-friendly-style-variants-in-tailwind-css-ui-components-part-1
I don't think it directly supports plugins, but you may be able to write custom plugins for tailwind-merge, as explained here: github.com/dcastil/tailwind-merge/blob/v1.12.0/docs/writing-plugins.md
How did you still get tailwind intellisense on the Button’s className props? Im not getting any tailwind suggestions on my end once I pass the className as props
You can extend the surface area of the Tailwind intellisense with the classList option: github.com/pro-tailwind/course-multi-style-components/blob/main/.vscode/settings.json#L5
I haven't done benchmarks or anything, but it indeed does have a tiny bit of runtime JavaScript. So it will never be as performant as "just CSS", but I think the impact is pretty minimal. tailwind-merge can run on the server (server components) and only the computed classes get sent to the client, nothing else. I would say, the performance hit is pretty minimal - but don't use tailwind-merge unless you have the sort of problems/challenges that tailwind-merge is helpful with! Hope it helps!
@TutoDS2014 Note that the absence of a run-time cost or including tw-merge in your JS bundle is true *only* of server components - if you have a regular component in a server-side rendering framework like next.js or Remix, even if if you don't use `useEffect` or change any props to cause it to re-render on the client, it will still render at least once on the client because that's how react hydration works, so tw-merge would still run in the browser in that case. Probably a minor concern for most projects, just explaining FYI
For some reason, it is no longer working on my setup! EDIT: If you are using prefix in the tailwind, make sure to extendTWMerge like this: import clsx, { ClassValue } from "clsx"; import { extendTailwindMerge } from "tailwind-merge"; const twMerge = extendTailwindMerge({ prefix: "tw-", }); export default function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); }
Not sure I totally understand the question, but I feel like this docs page should get you going: github.com/dcastil/tailwind-merge/blob/v1.12.0/docs/configuration.md
You probably can't. Tailwind merge is JavaScript that runs when your component function is executed, at run time. It does its conflict resolution in JavaScript, so you won't be able to do this in a CSS file. You can probably use it in a Tailwind plugin though, since twMerge works on the server as well.
So, as very much a beginner: the "className" prop is available on the component (in this case, Button), and so we use TW-merge to bring in any "overriding" TW styling and merge it with the styling we've declared for the component. That way, we can still use our reusable component wherever we want, but if we want to make it a different variant, we can just pass whatever changes we need. Would it be wise to have a different prop passed in? Like, let's say that we want the button to be a warning style, so we'd change the background and text color to shades of red and we wanted the shadow to be larger. We could pass those in via "className", but maybe we could also pass it as a custom prop called "style" (e.g. "style" would be "warning" in this case) or something and then have logic within the component that would handle the styling?
Yep, absolutely. You typically would have specific style "variants" via props like "size", "impact", "tone" etc where you can handle custom styles. Passing a classname attribute (can also be another prop name) is more of an "escape hatch" when you want to do something very unique/werid/one-off.
In one of my Pro Tailwind workshops, we cover precisely what I think you're asking for, in case you're interested: www.protailwind.com/workshops/multi-style-tailwind-components
It's mostly the Tailwind Intellisense extension. Outside of that, I use prettier with format-on-save, and the prettier-plugin-tailwindcss Prettier Plugin for class sorting. Night Owl theme (light or dark), Dank Mono font. That's about it!
Hey Simon, I'm a first timer just discovered your channel and I love it, just wanna ask you about your browser, is it customised or what? it looks beautiful
This is ARC browser - it looks like this by default and you can customize a lot of things. An absolute treat for scresncasts, and all chrome devtools / extensions work seamlessly 💫
Yeah i know, but what is the point to have className with the same conflicting CSS ? If we wanna do p-5 then why do we need p-6 for? And for Responsive Design we can do it like sm:p-5 md:p-6 p-6 . What I'm trying to ask is, why do we need to override classes and what's the point of having conflicting properties?
There is no point having conflicting properties, ever. But there are many scenarios where you accidentally end up with conflicting properties - or cases where it's tricky to avoid those or make a specific one "win". Tailwind Merge helps with that.
May I know why did you stop making video in tailwind labs Simon? Anyway, upload here or in tailwind labs, doesn't really matter as long as you upload new tutorial. Keep up the good work. Have a nice day.
The answer is very simple: I got fired. One day, as I was editing a video, I got the good ol' "Hey, got 5 min to chat" DM on Discord. 5 minutes later, I was cut from the team, and removed from the UA-cam channel. Surprisingly, there is only one new video on the channel in 1+ year. Turns out making good videos is hard and time-consuming, as they found out! I honestly think they decided to rely on community influencers like Sam Selikoff or Theo to substitute the need for a first-party UA-cam channel. I was loving my job and had no intention of going anywhere.
@@simonswiss bro... I never thought it was because of that. Sorry to hear that. Wish you all the best bro. Hopefully your channel can grow as big as tw lab. With your knowledge & method of teaching, I'm sure it will. Keep up the good work.
This is cool but I would be concerned about using this on a server side rendered page. Given a page has hundreds or thousands of twMerge calls and a server has a lot of traffic that's a lot of extra function calls for just a bad className design in the first place. There's the !important variants that exists that can do exactly this and better code overall will help more than this IMO
A thousand twMerges in one single page? Yeah that's probably a lot.. !important variant is great indeed, but it assumes you *know* what classes are conflicting, so you can decide which one should win.
It is definitely Dank Mono. I am sure 100% because I also use this font for more than a year already. The f that goes below the line is unique in that font (among other stuff like italics of course).
You need to config all custom classes in tailwind config for twmerge config also (so you have to config your custom classes twice) and if you make something like className = {twMerge("w-96", "w-full")} it is not working, so bug.
Hmmmm, component classes typically affect multiple CSS properties, so it would be pretty hard to merge those. I haven't tried, but I don't feel like passing a component class to a UI component with its own styles is gonna go too well in any scenario. Passing classes to a component is usually a one-off, escape hatch way of doing a change you really need to. Not the primary way of composing styles, in my opinion.
Which one? twMerge? It's not a class, it's a JavaScript function. It's neither React nor Tailwind, it's... its own thing 👍 But yes it works *with* Tailwind and React (and I imagine other JS frameworks).
Hmmm because the function is what contains the logic to resolve conflicting classes? You can definitely do it all manually with string concatenation and interpolation. If you know exactly what you are doing - and then no runtime cost 👍
Do you mean the Rodecaster Pro? It's an overly fancy audio interface/podcasting station. That said I do have a midi keyboard on my desk, but just off camera! 😅
I keep seeing this stuff because at work I'm forced to use tailwind. I can't believe people are buying tailwind, I can't believe people are excited for these solutions that would not be needed if not using tailwind in the first place. I can't believe people getting excited for a new tw version that supports x feature that css has supported for years... all of it because they don't like coming up with names for the elements to use as classes. Guess what... you still need to come up with names for your components, and you're left with a bunch of new issues, which is why you're now on yt watching this. :facepalm:
Tailwind CSS is free. I guess you mean Tailwind UI templates/components. And I can't believe you spent the time to complain about all of this in a UA-cam video. Most people use Tailwind because they love the productivity and confidence they get with it. Not naming classes is just one aspect of that productivity boost.
@@leanazulyoro Ah, gotcha - "buying into" Tailwind. I originally thought the same with Tachyons, and most people do start by hating/rejecting it. If you still don't like it after using it... I am sorry you are forced to use it at work. On the flip side, I ended up quitting jobs because I could not use Tailwind and I was becoming miserable 😅
Believe it or not, I've tried many times, in shorter form, and the message was not received. I also have a 2:20 version of this video on Twitter. I am terribly sorry for wasting 12 minutes of your life, happy to provide a refund on this free video 😅
yes, this one removes conflicts p-4 and p-5 get merged into "p4 p5" which doesn't make any sense in clsx in tailwind merge they get merged into just "p5" that gets rid of some of css conflicts that DO EXIST, you can research it yourself if you are interested.
clsx works great but will not resolve conflicting styles, so you'll sometimes have unexpected results, just like the video explains. twMerge is very similar to clsx, but does ensure only one class per CSS property is being set on the element when merging strings.
Probably one of the best videos explaining the problem, a solution that doesn't work and explain why, then go on to present a better solution. This is quite rare in tech videos, which often skip over the why's and hows. Kudos!
Thank you, I appreciate this comment that balances the "get to the point, you wasted 10 minutes!" comments. Glad you enjoyed the progressive explanation - I wanted the message to land properly.
@@simonswiss You will always have people who don't know how to use the UI to skip parts in a video. Keep creating good content for people who care :)
That's a good way to look at it, thank you! 🙏
@@simonswissi’m new but i’m loving it ❤
@@abhyuday911 Thank you so much! ❤
The brightness of this video has left me blind for the rest of my life.
I am preparing you for the outside world when it's time to go get some fresh air 🤗
well explained. I was beginner learner and stuck in this problem. went thorugh your video and just fully satisfied. Thank you so much !!
You are welcome!
In my full time job, we use WP as a headless CMS, and this library has solved a lot of issues when pulling the classes from the blocks.
Yeah that's a great use case for that scenario!
Awesome video bud, as a library author I have been getting stuck in this like sneaky problem.
Glad I could help!
Thanks for explaining the problem. I ran into this when updating tailwind, all of a sudden everything looked wonky. I looked into twmerge but felt like it was a hassle to update the whole codebase to call a utility function. Feels like something that should be solved at compile time.
Make more of these tailwind videos! Love it
Yeah, a lot of folks seem to love it, and I love it too :)
Found you on Laracasts, thanks for this great content and vibes man God bless 🙌
Am I on Laracasts? Do you mean in the comments?
@@simonswiss Yes in the comments section, it was motivating learning with you and others.
@@edriso haha awesome!
Cool video Simon. One of the best explanations of this problem in TWCss.
Glad it was helpful! Yeah I tried to explain it as good as I could, even if it took a bit more time to deliver 👍
Very comprehensive! Thank you so much!
Super glad you enjoyed the video!
Very clear and useful, thanks !
Glad to hear that!
Pretty cool tool, thanks for showing us!
Yeah, it's really good 👍
Hey Simon, would you please consider using dark mode? The white screen flashbang is really hard in the eyes, especially at night, and I mean hard as in squinting my eyes and then giving up on the video. Love your content and I hope you give this some thought.
Thanks for the suggestion. I struggle with the opposite with my eyes, but you make a good point. I usually use Night Owl Dark and no one ever asked for light - so I'll do the next video in dark theme!
Never thought the opposite was algo possible! It makes sense. But yes, flashbangs are something that always gets comments throughout UA-cam, and some UA-camrs even warn before one happens.
Keep up the good work bud, and I'd love to hear your take on tailwind and toast notifications solutions like react-hot-toast that don't make it necessarily trivial to integrate with it.
I agree. It just piercing
You shouldn't watch anything in darkness anyway. That's bad for your eyes, like really bad. You should always have some kind of light.
I am coding just fine with a light theme at 3am. Why? Because I have the fricking lights on.
Hi Sunday, Maybe try watching the video during the same time of day as Simon
Awesome Video buddie!
Thank you!
9:52 You've been waiting for THIS part for almost 10 minutes.
The thing is that this library opens the gateway to tailwindized component libraries all over the place.
You will finally be able to Bootstrap + Tailwind with no issues (I guess)
Can't appreciate the destination without embracing the journey 🤗
It's good to explain the problem before showing off the solution. But a timestamp would be appreciated for people that just want to see how it works!
@@GameDSS There are chapter timestamps in the video description and you can see them on the video timeline 👍
Thanks Simon for recording this video and explaining the why.
What would you recommend doing in situations where I’d like to allow the users of to override certain classes (e.g. ) but restrict (or, at least warn) users from overriding other classes (e.g. )?
Thanks! In that scenario I think it makes sense to setup a few style props for spacing, width etc instead. Sort of how Theme UI or Shakra UI work, if you are familiar with them. Or a "layoutClasses" prop that only allows "contextual" classes (width, margin, display etc). Might be a bit confusing for the user though 😅
1. U can add jsdoc to the `className` prop, and tell users about ur intention
2. U can add, for dev mod only, runtime checks and logs. This can be a little bit complicated bcs u need to cover custom matching (or maybe there is already a solution idk)
i like your video. Clear and well explained. Kudos!
That's pretty cool. I've never had that issue, didn't even know that was a thing. But now that I stop for a second and think about it, it seems obvious. And also, I wonder why I've never seen this issue, since it seems like I should have. Although I might have hacked a workaround to something just like it the other day!
Maybe you got lucky with alphabetical color overrides, and always passed classes generated lower in the CSS output 😅
@@simonswiss Maybe. I also tend to handle situations like your example by defining a "theme" property on the button, then handling the selection of classes entirely within the component rather than passing classes in. So I've probably mostly avoided it using different design patterns.
Yep, what you describe (style variants via props) is definitely the way to handle various styles.. but even then, I had accidentally a sneaky conflicting padding classes combo when having 4-5 composable style variants, even trying to be careful with separating styling concerns between 'size', 'look' 'shape' etc.
Can indeed be avoided but sometimes it becomes quite involved with multi-style variants.
Another tool that can help with that is CVA by Joe Bell - will probably do a video on that as a pretext to try it out!
@@simonswiss Yeah, padding was one I was specifically thinking of. The number of times I must have mixed sm:p-, p-, px- and pl- or pr- together on the same div and seem to have gotten away with it. Granted some of those will be different CSS properties, so CSS would presumably resolve that conflict internally. There's a few times, I've found myself thinking "The class is at the end, so it must be winning". which as you pointed out in the video is actually CSS order, not class order. So I feel like I must have been down this rabbit hole without recognising it, then hacked my way out without really understanding what I'm doing.
`tailwind-merge` also supports custom conflicting class names.
let's say we have custom class names that should conflict if we pass it together, e.g `alert-success`, `alert-error`, `alert-info`
if you use normal/default `twMerge`, it can't detect the conflict because `alert-success`, `alert-error`, `alert-info` is not supported by tailwindcss by default.
but we can use `extendTailwindMerge` or `createTailwindMerge` and define our custom conflicting class names
pretty neat
Yeah, that's really cool! Have not used this myself, but I saw it in the README docs 👍
Such an intelligent video, thanks for making!
Thank you, glad you enjoyed it!
Thank you! really love your explanation
That's great to hear, thank you!
This is super useful!
Definitely can solve a bunch of subtle problems!
excellent explaination
Glad you liked it!
Thanks Simon, can we have a video on how to make reusable components with Tailwind ?, Where UI can be customized using props. Similar to how MUI and other component libraries work.
It's not free, but I have a Pro Tailwind workshop on exactly that, which I think you'd like: protailwind.com/workshops/multi-style-tailwind-components
I also have a free article covering _some_ of the contents, you might start with that :)
www.protailwind.com/just-in-time-friendly-style-variants-in-tailwind-css-ui-components-part-1
Awesome explanation video!
Thanks Noah! That would work perfectly well in the components we built in the Multi-Style Tailwind Components workshop :)
Great tutorial!
Thank you, happy yo hear you enjoyed it!
I got something to do tomorrow 😱 what a lovely package. No more bang classes 🎉
Does this fully work with custom extend items and prefix plugins?
I don't think it directly supports plugins, but you may be able to write custom plugins for tailwind-merge, as explained here: github.com/dcastil/tailwind-merge/blob/v1.12.0/docs/writing-plugins.md
How did you still get tailwind intellisense on the Button’s className props? Im not getting any tailwind suggestions on my end once I pass the className as props
You can extend the surface area of the Tailwind intellisense with the classList option: github.com/pro-tailwind/course-multi-style-components/blob/main/.vscode/settings.json#L5
Ohhh nice one ! Thank you !
You're welcome!
Amazing, didn't know there was something like that
Yeah, its pretty useful!
One question, what the impact on performance when use the `twmerge`?
I haven't done benchmarks or anything, but it indeed does have a tiny bit of runtime JavaScript. So it will never be as performant as "just CSS", but I think the impact is pretty minimal. tailwind-merge can run on the server (server components) and only the computed classes get sent to the client, nothing else.
I would say, the performance hit is pretty minimal - but don't use tailwind-merge unless you have the sort of problems/challenges that tailwind-merge is helpful with!
Hope it helps!
@TutoDS2014 Note that the absence of a run-time cost or including tw-merge in your JS bundle is true *only* of server components - if you have a regular component in a server-side rendering framework like next.js or Remix, even if if you don't use `useEffect` or change any props to cause it to re-render on the client, it will still render at least once on the client because that's how react hydration works, so tw-merge would still run in the browser in that case. Probably a minor concern for most projects, just explaining FYI
what if the base styles you want to override are defined in css stylesheet,
className={twMerge(`input-group`, 'border-danger-900')
this doesn't work
For some reason, it is no longer working on my setup!
EDIT: If you are using prefix in the tailwind, make sure to extendTWMerge like this:
import clsx, { ClassValue } from "clsx";
import { extendTailwindMerge } from "tailwind-merge";
const twMerge = extendTailwindMerge({
prefix: "tw-",
});
export default function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
Thanks for sharing!
@@simonswiss You're welcome
How does it works if I have a custom tailwind config based on a style guide?. Do I have to make any modifications?
Not sure I totally understand the question, but I feel like this docs page should get you going: github.com/dcastil/tailwind-merge/blob/v1.12.0/docs/configuration.md
Thanks for this video, one quick question:
How do you guys handle tooltips on disabled elements(Button, Inputs, ...exc) ?
I haven't had to do that before, not quite sure how to answer this without looking at a specific example!
How can we use tailwind-merge with @apply in css files? Thanks
You probably can't. Tailwind merge is JavaScript that runs when your component function is executed, at run time. It does its conflict resolution in JavaScript, so you won't be able to do this in a CSS file.
You can probably use it in a Tailwind plugin though, since twMerge works on the server as well.
So, as very much a beginner: the "className" prop is available on the component (in this case, Button), and so we use TW-merge to bring in any "overriding" TW styling and merge it with the styling we've declared for the component. That way, we can still use our reusable component wherever we want, but if we want to make it a different variant, we can just pass whatever changes we need. Would it be wise to have a different prop passed in? Like, let's say that we want the button to be a warning style, so we'd change the background and text color to shades of red and we wanted the shadow to be larger. We could pass those in via "className", but maybe we could also pass it as a custom prop called "style" (e.g. "style" would be "warning" in this case) or something and then have logic within the component that would handle the styling?
Yep, absolutely. You typically would have specific style "variants" via props like "size", "impact", "tone" etc where you can handle custom styles. Passing a classname attribute (can also be another prop name) is more of an "escape hatch" when you want to do something very unique/werid/one-off.
In one of my Pro Tailwind workshops, we cover precisely what I think you're asking for, in case you're interested: www.protailwind.com/workshops/multi-style-tailwind-components
@@simonswiss Thank you! Cool, I'll check it out!
Great video as always! Could you please share the VS Code plugins you use for tailwind and such? Thanks
It's mostly the Tailwind Intellisense extension. Outside of that, I use prettier with format-on-save, and the prettier-plugin-tailwindcss Prettier Plugin for class sorting. Night Owl theme (light or dark), Dank Mono font. That's about it!
may i have your font style and color theme of vscode? love it very much, thx
Dank Mono font - Night Owl theme ✨
Hey Simon, I'm a first timer just discovered your channel and I love it, just wanna ask you about your browser, is it customised or what? it looks beautiful
This is ARC browser - it looks like this by default and you can customize a lot of things. An absolute treat for scresncasts, and all chrome devtools / extensions work seamlessly 💫
Also, thank you for your kind words on my channel, and welcome aboard!
What fonts are using for your editor
Dank Mono 💫
Yeah i know, but what is the point to have className with the same conflicting CSS ? If we wanna do p-5 then why do we need p-6 for? And for Responsive Design we can do it like sm:p-5 md:p-6 p-6 . What I'm trying to ask is, why do we need to override classes and what's the point of having conflicting properties?
There is no point having conflicting properties, ever. But there are many scenarios where you accidentally end up with conflicting properties - or cases where it's tricky to avoid those or make a specific one "win". Tailwind Merge helps with that.
@@simonswiss oh I see, thank you
No worries, you're welcome!@@shinobi_coder88
May I know why did you stop making video in tailwind labs Simon?
Anyway, upload here or in tailwind labs, doesn't really matter as long as you upload new tutorial. Keep up the good work. Have a nice day.
The answer is very simple: I got fired. One day, as I was editing a video, I got the good ol' "Hey, got 5 min to chat" DM on Discord. 5 minutes later, I was cut from the team, and removed from the UA-cam channel.
Surprisingly, there is only one new video on the channel in 1+ year. Turns out making good videos is hard and time-consuming, as they found out!
I honestly think they decided to rely on community influencers like Sam Selikoff or Theo to substitute the need for a first-party UA-cam channel. I was loving my job and had no intention of going anywhere.
@@simonswiss bro... I never thought it was because of that. Sorry to hear that.
Wish you all the best bro. Hopefully your channel can grow as big as tw lab. With your knowledge & method of teaching, I'm sure it will. Keep up the good work.
@@syamsarosa5916 thank you so much ❤️❤️
This is cool but I would be concerned about using this on a server side rendered page. Given a page has hundreds or thousands of twMerge calls and a server has a lot of traffic that's a lot of extra function calls for just a bad className design in the first place. There's the !important variants that exists that can do exactly this and better code overall will help more than this IMO
A thousand twMerges in one single page? Yeah that's probably a lot.. !important variant is great indeed, but it assumes you *know* what classes are conflicting, so you can decide which one should win.
What coding font is that? interesting
I guess it's Operator Mono by Hoefler&Co. It's a paid font; however, I vaguely remember there's an open source 'replica' available.
It is definitely Dank Mono. I am sure 100% because I also use this font for more than a year already. The f that goes below the line is unique in that font (among other stuff like italics of course).
Dank Mono!
Nope, Dank Monk. Also a paid font, but significantly more affordable!
You are indeed 100% correct!
can u describe the video in braile pls I just went blind from all the light mode
Sorry, can't see your comment, also looked at my own light theme.
You need to config all custom classes in tailwind config for twmerge config also (so you have to config your custom classes twice) and if you make something like className = {twMerge("w-96", "w-full")} it is not working, so bug.
so is that better than clsx?
It's different! clsx doesn't merge conflicting Tailwind classes - but if you only need to combine classes, clsx may be better!
does it work for react native ?
thanks for this
by the way, I'm confused about whether it should be installed as a dependency or devDependency. what do you think?
@@marvelbox dependency, because it's a runtime library 👍
@@simonswiss such a quick reply. thanks a latte
real game changer, but notcied it doesn't work with component classes e.g @layer components
Hmmmm, component classes typically affect multiple CSS properties, so it would be pretty hard to merge those. I haven't tried, but I don't feel like passing a component class to a UI component with its own styles is gonna go too well in any scenario.
Passing classes to a component is usually a one-off, escape hatch way of doing a change you really need to. Not the primary way of composing styles, in my opinion.
Is this a Tailwind class or a React?
Which one? twMerge? It's not a class, it's a JavaScript function. It's neither React nor Tailwind, it's... its own thing 👍
But yes it works *with* Tailwind and React (and I imagine other JS frameworks).
I love it
It's really good!
WOW
I know, right?
why not just join the className as a template literal and avoid the function?
Hmmm because the function is what contains the logic to resolve conflicting classes? You can definitely do it all manually with string concatenation and interpolation. If you know exactly what you are doing - and then no runtime cost 👍
Are you fo real my brother in Christ? Light mode !!!!!!!!!
Your avatar is too dark, I can't see a thing 😅
@@simonswiss exactly
@@hakuna_matata_hakuna So I thought!
Yeay!! more fugly jsx code :)
Vi ka li det!
@@Hurtwolf det er syre for øjnene
@@LarsRyeJeppesen Jep. Har også installeret "Inline Fold" Extension.
that is why, its better to use unocss xD
nice, a midi keyboard
Do you mean the Rodecaster Pro? It's an overly fancy audio interface/podcasting station.
That said I do have a midi keyboard on my desk, but just off camera! 😅
I keep seeing this stuff because at work I'm forced to use tailwind. I can't believe people are buying tailwind, I can't believe people are excited for these solutions that would not be needed if not using tailwind in the first place. I can't believe people getting excited for a new tw version that supports x feature that css has supported for years... all of it because they don't like coming up with names for the elements to use as classes. Guess what... you still need to come up with names for your components, and you're left with a bunch of new issues, which is why you're now on yt watching this. :facepalm:
Tailwind CSS is free. I guess you mean Tailwind UI templates/components. And I can't believe you spent the time to complain about all of this in a UA-cam video. Most people use Tailwind because they love the productivity and confidence they get with it. Not naming classes is just one aspect of that productivity boost.
@@simonswiss didn't mean "buying" in the literal sense
@@leanazulyoro Ah, gotcha - "buying into" Tailwind. I originally thought the same with Tachyons, and most people do start by hating/rejecting it. If you still don't like it after using it... I am sorry you are forced to use it at work. On the flip side, I ended up quitting jobs because I could not use Tailwind and I was becoming miserable 😅
The button example is not so contrived 😂
Yeah lol buttons can get crazy. This particular example was pretty dialed down 😅
Coding in white theme should be a CRIME
It's terrible isn't it? But it's too bright out here and I can't deal with the glare in dark themes 😅
12 mins of explaining something so simple........................................................................ get to point damn it!
Believe it or not, I've tried many times, in shorter form, and the message was not received. I also have a 2:20 version of this video on Twitter. I am terribly sorry for wasting 12 minutes of your life, happy to provide a refund on this free video 😅
Use the chapters 🙄
Your IDE preference are sinful 😂 jk
So I am being told in these comments 😅
Noted, noted 🤣
clsx works fine, am I missing something?
yes, this one removes conflicts
p-4 and p-5 get merged into "p4 p5" which doesn't make any sense in clsx
in tailwind merge they get merged into just "p5"
that gets rid of some of css conflicts that DO EXIST, you can research it yourself if you are interested.
clsx works great but will not resolve conflicting styles, so you'll sometimes have unexpected results, just like the video explains. twMerge is very similar to clsx, but does ensure only one class per CSS property is being set on the element when merging strings.
React is needlessly complex.
For this simple example, yes, but it's very useful for more advanced stuff!