arcanemachine

arcanemachine

This was the first question on my mind when I saw this other thread by @AstonJ.

I’m curious how many Phoenix users actually like using Tailwind.

Do you prefer to use Tailwind in your Phoenix projects?

  • Yes
  • No
0 voters

Showing Posts 1 to 10

tfwright

tfwright

I understand the criticisms of Tailwind, but I see it as a nice midway point between bland/difficult to maintain Bootstrap-y component classes and unintuitive, clunky vanilla CSS. It suits me as a ““full-stack”” backend developer, which I also think happens to be a good pitch for the average person getting started with Phoenix. Then again I haven’t had to professionally maintain CSS in a while, and from what I observe my FE colleagues doing I’m guessing it’s probably a bit in the way. But like most experienced Phoenix users, I’d guess they make heavy use of the --no-assets option.

Eiji

Eiji

I don’t like it for a few reasons:

  1. It’s forced by default in a way it’s not easy to remove. Standalone it would be not a big deal if we talk only about a single generator, but if we have to rewrite each generated template then we simply waste time and it’s against Elixir’s 10x rule where we focus on writing the app’s logic.

  2. .css files is not some kind of an old standard that’s currently useless - it exist for a reason. Styles are supposed to be separated from templates and not be part of them. If that would be the case then we would use style attribute instead of class for Tailwind. The Tailwind is overusing class attribute making it harder to read especially for people that does not know all of it’s shorter naming.

  3. I’m definitely ok with an idea to keep template code and it’s styles in the same place as I said in another post, but same place (with extra macro above template function or so) does not mean part of template. This makes templates code longer and therefore harder to read. Think if someone would not format templates and would put all element attributes in same line with class as a first attribute. This way we would have to scroll the code just to find things like phx-click which sounds more like anti-pattern than a standard.

  4. Tailwind defines a shortcuts for styles. It does not introduce anything besides it. It would be nice if above template function there is a single line macro, but in a more complex case it’s just a long string of abbrevations our brain has to parse over and over again. It’s not using advanced CSS and SCSS rules like nesting, variables, counters, scopes and many more. It’s kind of pre-generated CSS abbrevations you have to configure and a framework that forces you a way of writing your code. It’s more like a framework that forces you to do things in specific way rather than a library that gives you useful tools.

  5. I remember that José Valim mentioned that the environment could be simplified (by getting rid of a node staff and so on) and it really happened and then they have added their own dependencies (Tailwind, DaisyUI). I would prefer to see Phoenix templates using SCSS features and variables that we can simply reuse in our code rather than what we have right now. The DaisyUI could be replaced with variables and a simple Colocated Hook, that saves theme to LocalStorage. Not only it would be a very good for learning purposes by using existing LiveView patterns, but also it would not be a theme framework that works over other framework.

  6. Tailwind may have compatibility bugs. It happened at least once and it was mentioned some time ago on forum for old macOS version. Neither CSS nor SCSS causes such a problems. Such problems are unacceptable for me. I don’t want that a JS file would not work, because I have too old or too new hardware..

I just wanted to explain that Tailwind and DaisyUI projects solves some problems in a way that does not fits Elixir/Phoenix/LiveView well. SCSS mixins and other functions are more than enough to make styles much shorter. esbuild for JavaScript and dart_sass for SCSS seams like more than enough dependencies we really need. The rest are some extra macros to make templates next to styles and a set of Phoenix variables, SCSS mixins and so on …

Please pay attention how SCSS extends CSS and how Tailwind limits CSS. There are many things that Tailwind needs a workaround to make some things working which just means more short naming than ever needed. If you ever wrote a CSS do you really feel a need to make @media query any shorter? What about a new CSS features that would be not supported until Tailwind would introduce another workaround for them? What’s the reason of using a terrible long class attribute if at the end in complex styles you still write your own CSS?

Tailwind was never an option for me. It’s not about how good or bad it really is. It’s about the way you want to write a code. It’s not like that everyday you fill a need to write some OOP code in Elixir, right?

12
Post #2
dimitarvp

dimitarvp

I can’t vote because I honestly don’t know the alternatives. I am trying to make a partial comeback to being a full stack but I am not rushing it at all and I might also give up. So far I am not impressed, people make stuff complex for reasons that I can’t easily decipher.

To me the maximum that should be done is to insert a tool in your chain (akin to rollup a while ago) that live-recomputes your CSS in dev env and makes a complete file in prod. Everything else is a distraction and it becomes a separate thing to maintain.

I do not want to pay attention to all this. It should have been solved 10 years ago.

garrison

garrison

Separating the styles from the markup was always a terrible idea. There was a notion that you could mark up your documents “semantically” with elements and then re-use styles across documents and documents across styles. This has systematically failed. Nobody does this.

So instead you’re just left cross-referencing a giant CSS file with a giant set of HTML templates. Total mess. Zero benefit. Bad idea.

In fact, just using the style attribute would be a wonderful solution, except for the fact that it sucks. It’s ancient and it wasn’t designed for this.

The correct way to do composability and re-use is not to apply the same styles to different elements but to group elements and their styles into components and compose there. This is what everyone does now. We do it with Phoenix too.

Tailwind, as a library, solves three problems:

  • Styles should be co-located with components
  • Styles should be composable (no name conflicts)
  • Design systems should work out of the box

Unfortunately, the utility class approach is fundamentally degenerate: it can never fully express CSS, and CSS is the thing which browser vendors actually support. So you are always playing catch-up.

The series of increasingly ridiculous hacks they have come up with to fit CSS into a class-shaped hole is something to behold. First they needed a compiler to strip the unused classes. Then they started dynamically generating styles at runtime with a made-up class syntax. So then they had to start shipping binaries just to compile CSS, and now they’ve even had to introduce a new Rust codebase to keep things performant.

There is a much simpler solution: web frameworks are already responsible for providing a component framework (we have HEEx). They should also be responsible for providing a scoped CSS implementation to go with it, and an extensible design system out of the box.

(See my comment in the other thread (linked in the OP) for an example of how this can be done.)

10
Post #4
sodapopcan

sodapopcan

c) Indifferent with a slight preference toward vanilla CSS.

Tailwind is great on projects where I’m the sole developer and I have to do everything including design on my own. I like to create my own components as opposed to using a CSS framework that gives you styled stuff out of the box, so Tailwind is great for that. I also find having style right in the markup easier to figure out coming into a project blind or looking at something for the first time in several months. Heavy emphasis on easiER, though, I meant that relatively.

I do know I’m sick of debating whether or not it’s generally a good idea.

Eiji

Eiji

Just one false assumption does not require me to respond to the whole point - that’s a terrible mistake from your side. Who said one giant file? Why you are assuming something that was not told? Why you put words in someone’s mouth? If you would read what I wrote you would know that I prefer SCSS and just like with esbuild the dart_sass allows to work on multiple files and merge them into single one.

I’m terribly sorry to shock you, but at least Bootstrap uses SCSS and does not use Tailwind. Whatever god you believe Tailwind is nowhere a common standard that could stand next to CSS or JavaScript. I didn’t check, but I guess same goes for other CSS frameworks …

And that’s true, because … you say that? Bootstrap devs are “nobody”? Do you follow all projects in the world including private ones? If I would say that nobody likes ice cream and you don’t agree with that then you are wrong, right? This is inappropriate way of discussion. As you said:

(for the community)

Oh, so the class attribute was designed for Taliwind … let’s check the dates … no. In theory there is no limit for classes as there is no only one right “limit” that would be ok for all projects, but putting 50 classes because you want to keep styles in template is the most messy thing I heard about. Using short naming is also a trouble.

Sure, we can talk with shorts all the time like when chatting using SMS messages many years ago, but this would be childish and hard to read for many people. As a senior developer I prefer rather explicit naming rather than shorting literally anything just to … what exactly? Write less characters? Since there is no tw- or tailwind- prefix there is no way to tell if let’s say hidden comes from tailwind, global styles or both. How does it even close to be a clean solution?

Yes, indeed. Wait, actually not … We write a hooks and currently a Colocated JavaScript and Colocated Hooks that are not the contents of phx-click and other attributes, but lives in standalone script element. I wonder from what alternative world you came actually. Tailwind is the only popular solution in Elixir ecosystem I know that is focused on putting everything into a single attribute.

And once again “nobody does this” or “everybody does that” is telling what they are supposed to that as otherwise they are wrong. This is not a forum discussion, but an order and a very bad one as typically people that found modern CSS features and SASS more useful in their projects are not going to listing to someone who is saying that they do wrong, because someone said that.

Oh, so you know the naming - that’s a good start. Now look twice how much JavaScript code you put in phx-click and other attributes and tell everyone that if they are not using JavaScript there it means they are all wrong.

That’s why in programming we use prefixes. If you pay attention you would find many of them … -webkit-, phx- and so on … There is no need to force an extra dependency just to skip prefixes. Like I understand that point. When I was starting with developing I also tried to short everything, make everything myself to make it the fastest and in that way I never finished any project, simply because I have focused on irrelevant things instead of delivering features.

If you want out of box solution then you use Bootstrap. You really don’t have to write any style unless you are going to add your own components … This way you would have out of box solution and a clean class attribute. Everybody wins. For sure out of box solutions force some styling and design, so all Bootstrap pages looks similar, but this is what you got for a ready and clean solution.

Edit; As mentioned in response below I focused on bad word and didn’t read carefully. It was because of 2 previous things already mentioned. Sorry, for this one.

Those argument are in fact ridiculous … We are talking in the context of colocated styles, right? From where stripping unused classes just came from? Why bringing compiler to topic when same could be done in the old-good metaprogramming?

That’s what I was talking about? Either macros or colocated styles … I don’t care which one would be better. Both would be completely different than what Tailwind provides. Still I would expect SASS support and I would still write some global CSS like some theming or layout variables added to :root selector or so. I’ve only mentioned that sometimes people need advanced CSS and SASS features and in that cases even if we would have to do that a bit manually it would be a much better. It depends on the project of course.

If you mention scoped styles then why you over protecting Tailwind then? It makes no sense. You defend one or suggest an alternative … In my point there is a real need for a CSS/SASS support in or around templates (implementation details are not that important if it fits well the rest). If I maintain the whole CSS or SASS code then I don’t have to worry about unused classes and optional features may be done using mixins and other features provided by SASS and soon also by CSS.

Eiji

Eiji

No, you are not. You’ve brought a very good arguments!

Exactly, otherwise it’s a complete mess as you don’t have comments and other things that makes your code clear for a bigger team.

That’s also very good argument, but you can do it in CSS or SASS too and for only this you don’t need Tailwind.

For me that’s not true as a single line of short naming that may even require extra scrolling does not looks well and easier to read. It would be more true if there would be a colocated styles that are scoped within specific component.

garrison

garrison

The section you quoted is about Tailwind. I first listed the problems Tailwind solves, and then described how that solution goes off the rails.

When Tailwind first started out they were shipping the entire set of utility classes. That quickly became too many, so they used a PostCSS pipeline to strip all classes which do not appear in your templates (by regex, basically).

But there is still a combinatorial explosion of modifiers (because they are hacked on top of classes) so in order to handle dark:sm:hover:bg-gray-100 and so on they wrote a compiler that instead reads the template source, extracts the classes, and generates them (as opposed to stripping them). They then went on to rewrite the compiler in Rust. As one does when one runs out of things to do I guess (sorry @dimitarvp lol).

Prefixes do not compose. Now you have to worry about prefix collisions instead. Hopefully you only have one component in your entire organization named button.

And yes, I am aware that there are various attempts to add more levels to this hierarchy and no, that is not a legitimate solution. By the time you’re done mangling your class names by hand your templates will look just as bad as Tailwind.

Because I have noticed in general (and this is not aimed specifically at you) that there is a whole lot of Chesterton’s Fence thinking going on in Tailwind conversations, where people complain about the downsides (which are considerable) while ignoring the reasons people do use Tailwind.

By recognizing the factors behind Tailwind’s success we can construct a better alternative. Personally I think scoped styles are a good candidate.

I think you have misunderstood my comment. The “utility class” approach is the approach taken by Tailwind. I am calling Tailwind degenerate because it will never be as expressive as the CSS it generates.

dimitarvp

dimitarvp

Haha, I appreciate the call out. Really. :003:

Obviously writing stuff in Rust does not make it good per se. But they reached for it because they really liked their approach and did not want to do something else so they at least wanted the performance to not stand in the way. But I’ll agree if you say that writing that in Rust was a way for them to not budge on their philosophy. That… seems a touch interesting of a choice, especially having in mind how crushingly true the following is:

Personally I have not gotten all the way to learning modern CSS or relearn SCSS / SASS. I might never do it, too, it’s really unclear what my direction will be even 2-3 weeks from now. I am getting super tired trying to always be a functioning fish out of the water – current work requires me to be super good with Ash and LiveView, both of which I knew next to nothing about just some two short months ago – and me saying “frak this CSS crap” next week is a very real possibility.

What truly baffles me is why isn’t all this stuff figured out already. Must we always clash on philosophical differences and make our own lives harder, and those of the people who use our stuff as well? How about we just build a thin layer on top of CSS that makes it less verbose while still being CSS and let people figure out what to do after? But I am guessing this has been tried as well, though I’ll happily admit almost full ignorance of this area.

It all seems like meaningless busywork though, when you zoom out and try to analyze it.

garrison

garrison

Oh I was 100% trolling, rewriting it in Rust was probably perfectly legitimate. Shipping a full NodeJS binary is more insane tbh.

Tailwind does not exist to make CSS less verbose. That requirement stems purely from their need to fit all of CSS into the class attribute without completely obliterating the markup (and yet the results are not great).

Actually all that is needed is to write normal CSS and then scope it. The components come out looking like this. I’m biased but I think it looks just fine!

But more importantly, the class names cannot collide because the selectors are mangled automatically (as opposed to by hand) by the compiler.

Another benefit which I have yet to mention in either thread is that this approach also looks great in browser DevTools. Unlike Tailwind which has no CSS classes to group by (because everything is CSS classes).

Where Next? Top

Trending in Polls Top

New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews