Blazorise icon indicating copy to clipboard operation
Blazorise copied to clipboard

Tailwind CSS

Open stsrki opened this issue 4 years ago โ€ข 26 comments

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/

stsrki avatar Apr 24 '20 06:04 stsrki

I spent some time looking into this myself a while ago.

Looks like a great fit for a Blazorise provider! Good choice!

MitchellNZ avatar Apr 24 '20 06:04 MitchellNZ

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.

AntonTurba avatar May 01 '20 18:05 AntonTurba

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.

ocgully avatar Aug 26 '20 00:08 ocgully

Tailwind CSS v2

MitchellNZ avatar Nov 18 '20 22:11 MitchellNZ

Was this started already? I would really like to see this happening.

marcusjm avatar Dec 21 '20 10:12 marcusjm

@marcusjm Unfortunately no. With all the other work, there is currently no time to commit to this big feature.

stsrki avatar Dec 21 '20 10:12 stsrki

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.

marcusjm avatar Dec 21 '20 10:12 marcusjm

There is no guide for this. You can always look at the source for existing providers.

stsrki avatar Dec 21 '20 10:12 stsrki

I suspected that was the case. Well then such a guide can be added to the wishlist :).

marcusjm avatar Dec 21 '20 10:12 marcusjm

I agree :)

stsrki avatar Dec 21 '20 10:12 stsrki

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. ๐Ÿ˜

Xeevis avatar Jun 01 '21 17:06 Xeevis

It seems like a good and easy approach. I wonder how it would work with a theme generator?

stsrki avatar Jun 01 '21 20:06 stsrki

Wow looks awesome. is there a timeline? I'm so excited. maybe there is something I can help with?

ParsaGachkar avatar Jul 04 '21 09:07 ParsaGachkar

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.

stsrki avatar Jul 04 '21 11:07 stsrki

Great

marcuscreatevision avatar Jul 12 '21 11:07 marcuscreatevision

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 ?)

tesar-tech avatar Dec 20 '21 09:12 tesar-tech

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.

stsrki avatar Dec 20 '21 10:12 stsrki

I recommend checking out Tailwind Labs and their video courses. It could give you some nice ideas how to move forward.

marcusjm avatar Dec 20 '21 10:12 marcusjm

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.

Xeevis avatar Dec 27 '21 16:12 Xeevis

This might come in handy: https://github.com/tesar-tech/BlazorAndTailwind

stsrki avatar Dec 28 '21 13:12 stsrki

https://daisyui.com/

stsrki avatar Aug 12 '22 09:08 stsrki

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.

timahrentlov avatar Sep 02 '22 08:09 timahrentlov

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 avatar Sep 02 '22 18:09 stsrki

@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.

tesar-tech avatar Sep 02 '22 21:09 tesar-tech

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?

timahrentlov avatar Sep 04 '22 09:09 timahrentlov

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));
}

Xeevis avatar Sep 04 '22 12:09 Xeevis

https://engstromjimmy.com/post/2022-10-03-BlazorTailwind

stsrki avatar Oct 03 '22 10:10 stsrki

Investigate how Tailwind is integrated into https://github.com/getspacetime/makani

stsrki avatar Nov 02 '22 11:11 stsrki

I have started with Tailwind support. Here is a quick showcase

image

image

image

image

image

stsrki avatar Dec 14 '22 12:12 stsrki

List groups

image

stsrki avatar Dec 16 '22 13:12 stsrki