Blazorise
Blazorise copied to clipboard
Tailwind CSS
https://tailwindui.com/
This is good candidate for the next Blazorise provider. The plan is to work on it sometimes before v1.0.
- https://jonhilton.net/tailwind3-blazor/
- https://chrissainty.com/adding-tailwind-css-v3-to-a-blazor-app/
I spent some time looking into this myself a while ago.
Looks like a great fit for a Blazorise provider! Good choice!
Would also greatly appreciate this option.
I had considering rolling some custom components using tailwinds, but realized it it didn't make much sense for my use case if I still had to load and fall back on bootstrap to use other Blazorise components.
I'd also like to request (beg) for this. I tried to use Blazorise on my existing tailwind css blazor site, and saw some odd results. Obviously Tailwind and Bootstrap collide.
Was this started already? I would really like to see this happening.
@marcusjm Unfortunately no. With all the other work, there is currently no time to commit to this big feature.
Sorry if I missed the obvious but is there a guide on deriving your own version in the docs? I was planning on using the UI features but then it couldn't be distributed since UI is not licensed that way.
There is no guide for this. You can always look at the source for existing providers.
I suspected that was the case. Well then such a guide can be added to the wishlist :).
I agree :)
I'm prototyping TailwindCSS JIT with Blazorise and it turns out it's far better to use existing provider as a starting point rather than starting from scratch. Since TailwindCSS is (as name implies) just CSS, you can utilize PostCSS and @apply
tailwind utilities to any classes from other frameworks. For this purpose I consider Bulma provider with it's naming scheme and structure a great choice.
Basically just ditch the provider's default CSS file, you'll be using the markup and class names, not the actual styles, these you'll generate yourself with TailwindCSS.
/* Using postcss-nesting plugin */
.button {
@apply inline-flex items-center justify-center px-4 py-2 text-base font-medium border border-transparent rounded-md shadow-sm whitespace-nowrap focus:outline-none;
&.is-primary {
@apply text-white bg-indigo-600 hover:bg-indigo-700;
}
&.is-secondary {
@apply text-indigo-600 bg-white shadow hover:bg-indigo-100;
}
& > {
img,
svg {
&.is-loading {
@apply w-6 h-6 animate-spin;
}
}
}
}
This approach has several benefits:
๐You can start designing components immediately, no need to bootstrap from scratch a new provider
๐TailwindCSS JIT can easily parse .css
/.pcss
files to generate on the fly only the styles you are actually using, so your resulting CSS is tiny even during development making for insanely fast refresh and dev tools usage while still providing full range of utility classes and all their combinations.
๐CSS hot reloads instantly without page refresh (as opposed to editing provider's .cs
files), you can design your components and immediately see changes upon save. You can work on any element on any page without losing state.
๐You have tried & proven reusable abstract class naming scheme (instead of making your own, or duplicating utility classes over and over again). It's also much harder to steal your designs.
๐If you stay true to what class originally intended and depending on chosen provider you get access to existing designs and UI kit components that will immediately fit inside your custom styling since they'll be using same markup and abstract class names.
๐There are no drawbacks. You are still free to derive and override any classes you want customized from parent provider (like Material provider derives from Bootstrap)
Hoping someone might finds this helpful when working with TailwindCSS and Blazorise. ๐
It seems like a good and easy approach. I wonder how it would work with a theme generator?
Wow looks awesome. is there a timeline? I'm so excited. maybe there is something I can help with?
We might try it in the v0.9.5 milestone after we release v0.9.4(around July 18th). @Xeevis's approach seems really good and hopefully, it will not be too hard.
Great
Few thoughts:
It would be super useful to make final tailwind.css
file buildable. If you use just one tailwind class in your project (let's say bg-red-500
), it will generate .css only with this one class.
So it require somehow find all of the classes from used blazorise components and user's code...
This process can be much easier now with tailwind v3, since they published standalone cli (no need for node.js). It would probably require to install this on user's machine.
I found Tailwindcss as the best option to add styling to my page and lack of this in Blazorise is keeping me doing some workarounds. Mixing it with bootstrap is not the best option (but can work with tailwind prefix)... On the other hand, up to my knowledge, Blazorise is the only Blazor component library, that is working on tailwind support. I may help with this one, let me know. (jak jsi na tom @Xeevis ?)
Tailwind CSS is a beast to implement. I think it will be the most difficult provider so far. @Xeevis suggestion seems like a good approach. But I'm not sure how it will fit into our ThemeProvider
.
What I don't like so far is that all the approaches require the use of some kind of build pipeline or a CLI. But since I didn't work with Tailwind CSS maybe I'm wrong.
I recommend checking out Tailwind Labs and their video courses. It could give you some nice ideas how to move forward.
Blazorise has no lack of support for TailwindCSS, it actually works great with it. TailwindCSS is a framework for quick & dynamic building of minimal stylesheets and since there are no premade components, there is nothing that could constitute a provider. That would make sense only for component libraries based on TailwindCSS like TailwindUI, RazorUI or Tailwind UI Kit etc. But most are commercial projects and their very markup is proprietary.
What everyone who wants to use TailwindCSS to create custom designs with Blazorise should be doing is to implement custom provider (see existing ones like Bulma to see how it's done). You can implement your own IClassProvider
and give Blazorise components your desired tailwind classes, you can also write .razor
components with tailwind classes and tell TailwindCSS JIT engine to scan those files.
But as per my suggestion, building the markup with utility classes from ground up is a tremendous chore. Most of the time you don't really care about the markup, as long as it's not limiting your ability to customize design of the component. That's why I suggested you use existing provider classes and just style them with @apply
and custom tailwind stylesheet. Also it's much quicker (instant) to hot reload .css
files than recompile .cs
or .razor
files which may from time to time trigger app restart.
This of course requires a build tool, Tailwind isn't static. Most basic is TailwindCSS CLI, you can also upgrade to PostCSS CLI (more features like imports, mixins, autoprefixing etc), but to quickly and automatically work with optimizations, typescript, PostCSS, ESM, NPM you may want next level like Vite.js or Snowpack.
This might come in handy: https://github.com/tesar-tech/BlazorAndTailwind
https://daisyui.com/
Keeping an eye on this one. Very exciting. In my experiments with TailwindCSS I found https://tailwindcss.com/blog/standalone-cli to be usefull. Oh, and Adam really dislike @apply (https://twitter.com/adamwathan/status/1559628176011165696) so be mindfull.
I hate that in order to use TailwindCSS, you have to use something that runs in the background. No other CSS framework requires that. It painfully reminds me of JS/TS/Node/React ecosystem.
@stsrki Yes, tailwind is special. It is not like other frameworks with crafted css files.
There may be a way around. I am thinking about tailwind play cdn. It is js library, which checks current page a create all the css in <style>
tag right inside the page. Not suitable for production. But in dev phase, it works like a charm.
Hmm. Perhaps TailwindCss is not a good idea. Perhaps one should simply "Blazorise" the idea and the utility concept of TailwindCss? Perhaps you should roll your own?
like
<div style="@(StyleExt .Align(Aligment.Top) .Center(Axis.Main) .Background(Sky.100) .SpaceY(5). ToCss() )"/>
and make it extensible so that devs can add their own css to this fluent syntax? And then step back and watch the "cambrian explosion" unfold?
TailwindCSS is a utility framework, it scans markup and stylesheets and compiles into minimal CSS stylesheet. It's like dotnet build
for your CSS, that's why it's so different to other opinionated CSS frameworks. When you choose tailwind you do so because it's fast and easy to create unique designs and still possible to opt to something premade. It's preffered if you inline all your styling into your component markup and never ever even touch CSS, but it's a tedious experience with current .NET tooling as it often needs to recompile and restart the app for simple cosmetic edits to show. Not to mention you need to override entire markup of any 3rd party components. Why bother when you can easily get away with any markup thus existing providers with the @apply
.
Oh, and Adam really dislike
@apply
(https://twitter.com/adamwathan/status/1559628176011165696) so be mindfull.
It's not that he hates @apply
per se, rather he hates people misusing it and flooding tracker with unnecesssary issues. It's meant to abstract tailwind classes and simple custom classes, but people mix custom classes which may even be nested, scoped or isolated in other files that are compiled separately.
To style a button you are ought to write
.button {
@apply relative inline-flex h-10 items-center overflow-hidden rounded-md px-4 py-2 text-sm font-semibold transition-colors;
@apply disabled:cursor-not-allowed disabled:opacity-70;
&.is-primary {
@apply bg-primary text-white;
@apply hover:bg-primary/90;
@apply active:border-primary;
}
&.is-secondary {
@apply text-primary bg-secondary;
@apply hover:bg-secondary/80;
@apply active:border-secondary;
}
}
// Or
.foo {
@apply (...)
}
.bar-1 {
@apply foo (...);
}
.bar-2 {
@apply foo (...);
}
<button class="button is-primary bar-2">Button</button>
But people even write this madness
.button {
@apply (...)
}
.button-group > .button:nth-child(2) {
@apply (...)
}
.button + .button {
@apply (...)
}
.primary-button {
@apply button; // What magic should be applied here?
}
I've been using @apply
with Blazorise and TailwindCSS CLI and I'm perfectly happy with it, watcher and hot-reload show immediate changes upon save and I don't have to care about markup of various components, can style virtually anything in any way with CSS selectors and powerful tailwind utility classes.
Also when you approach tailwind more abstractly you can write your styles in a way that they are easily configurable. Eg. don't bake in bg-red-500
style but rather create new color called danger and use bg-danger
, border-danger
etc instead. You can then change style of all danger components on your entire site in single config or CSS variable. You can use theme()
function for using TW variables with raw CSS.
.content-area {
@apply bg-danger border-danger text-danger;
height: calc(100vh - theme(spacing.12));
}
https://engstromjimmy.com/post/2022-10-03-BlazorTailwind
Investigate how Tailwind is integrated into https://github.com/getspacetime/makani
I have started with Tailwind support. Here is a quick showcase
List groups