Improve phx.new -no--tailwind?

I started a new phoenix project with --no-tailwind and found friction:

  1. delete tailwind classes from core components
  2. delete tailwind classes from layout files
  3. figure out how to add my own style sheet (not obvious that I needed to import it in app.js )

I believe this is technically working as intended as the docs say:

the generated markup will still include Tailwind CSS classes, those
are left-in as reference for the subsequent styling of your layout
and components

However, I feel that they are more of a hindrance. Most people using -no–tailwind probably have no interest in learning what all the class names mean.

I’d like to contribute a PR to phoenix that removes the tailwind classes when the project is created with --no-tailwind. Additionally, I’d like to add a very basic style sheet. This would make the generated pages a bit more usable and provide a nice example/starting point on adding additional css.

I want to gauge the interest/feasibility from the community before spending time on this though. Thoughts?

5 Likes

This has nothing to do with phoenix, it is related to esbuild.

You should consult the source code first, there must be a reason those classes are not removed when --no-tailwind option is used, my thinking is that it will create a lot of boilerplate ifs in the generated templates, but once again it would be great to not have the classes for projects that are not using tailwind.

2 Likes

It‘ll be the exact same problem given your proposed solution. Just added on top that it would require learning a custom css setup, which is not vastly documented with lots of resources online.

And I wouldn‘t expect the phoenix team to be interested in maintaining multiple versions of the same, or worse similar, styles in tailwind as well as in a custom setup.

2 Likes

@LostKobrakai yeah, I agree now that we shouldn’t add another style sheet, good point about maintenance burden.

@D4no0 I looked at the source code and yeah, it wasn’t obvious how to implement this. I agree that an if statement in every html element isn’t a viable solution. What about applying a post processing script that strips the value from every class="blah blah" after the files are generated?

I’m still curious if any non-tailwind users find the tailwind classes useful in the generated code.

Personally I like tailwind, I just don’t think it’s the right fit for every project.

Yes and no

Yes, because there is definitely no point in complicating default phoenix generators and by default a developer should think about writing it’s own generator, but 
 :+1:

For what reason LEEX and whole component system has been introduced? Wouldn’t that be easier if all Tailwind classes would be used in core_components.ex only? Assuming that we want to create a phx.new like generator all we want to do is to use a single flag and provide our own core_components..ex when needed. :thinking:

The topic should already end here and I honestly don’t see why core developers decided to force Tailwind in a way it takes extra time to rewrite generated templates which is exactly against the component concept. :icon_confused:

We could argument it wider. One of important thing in Elixir is 10x rule, so we need to write 10x less LOC focusing on main application features + the other rule saying Elixir is easy to extend which was mentioned for example when introducing nx project. In this case however we need to spend time on rewriting already generated templates or part of existing phx.new generator before we would work on our original idea. Ok, we can easily copy-paste the mix tasks, but going this way should we also provide our own Elixir core features? I guess it’s a bad practice and wrong way of thinking, no? :no_entry_sign:

As senior developer I understand the decisions of core developers including why Tailwind is a default choice, but at the same time I can’t agree with a way of introducing Tailwind in phx.* generators (having in mind component stuff as an easy alternative). :-1:

That’s another edge-solution. Much simpler would be as said using components end-to-end and simply not generate core_components.ex file. If somebody wants to have a bootstrap application then simply would need to write a custom components or use an existing library which is not focused on maintaining a copy of phx.* tasks, but on said components.

Exactly, same as PostgreSQL. Now let everyone think how hard is to change database? Same should be done with all the CSS stuff.

2 Likes

Greetings Everyone!!!

A little bit of my background so it could be easier to understand where my comments are coming from, and to take them with a grain of salt
or lots of.

I started coding back in 1989. A few years later I was writing code with VIM in Unix: FoxBase+ and C. So, I am very used to code on a simple and fun programming language, and in a not so fun but powerful language, hence, I am used to allocate memory when needed and freeing it when no longer needed, and yes, I still use Short integers when available: The very first computer I used had 128Kb of RAM, the Tandy Color Computer 3. Some habits are hard to break, and I really want my programs to be thin and light. I am barely starting with Elixir, Phoenix, LiveView, HTML and CSS, thus
 I really see no point on using Tailwind. I started using Linux in the mid '90s because I love the freedom it provides, so I totally agree that everybody is free to choose if they want to use Tailwind or not. Everybody is free to chose their poison. No questions asked (my VERY PERSONAL point of view).

I agree with @knoebber, @eiji and @D4no0: If the user entered the --no-tailwind parameter, there should be no Tailwind code in the project.

I disagree with both 



 and 


This is because I think a ‘style sheet’ already exists, even though it doesn’t. If you create a project without Tailwind, the LiveView page you create after that won’t show any CSS formatting (so, no style sheet actually exists), but there are lots of Tailwind classes already mentioned (so, some sort of style sheet exists, it just happen to have empty references).

I kind of agree with @knoebber but with a slightly different approach.

Here is what I think (my very personal point of view):

As the documentation says The generated markup will still include Tailwind CSS classes, those are left-in as reference for the subsequent styling of your layout and components. This kind of defeats the purpose of the –no-tailwind parameter, because, even though it is not configuring the project to use Tailwind (as requested), it is leaving Tailwind classes as empty references, i.e., misinterpreting the “I don’t want to use this CSS Framework” with some sort of “I don’t want to use CSS”.

I just created an app with the –no-tailwind parameter, checked the core_components.ex file and the first class statement there says:

  def modal(assigns) do
    ~H"""
    <div
    [...]
      class="relative z-50 hidden"

I haven’t checked where this class value comes from. My first guess is it is hard-coded somewhere, but lets just say it comes from the source. At this point I want to think the source already knows what that division’s attributes should be, since it has a class value in it, so we already have a style definition. As far as I understand, Tailwind would have created three classes in the priv/static/assets/app.css file:

.relative{
  position: relative;
}
.z-50{
  z-index: 50;
}
.hidden{
  display: none;
}

Since the purpose is to get rid of Tailwind, but to keep some sort of references for the subsequent styling (that’s why they are leaving references behind, right? Empty references, but references whatsoever), let’s get rid of the Tailwind classes, but leave references to actual CSS styles: the parameter is named --no-tailwind not --no-css.

Instead of the source defining empty Tailwind references in core_components.ex, lets have the source to name classes pointing to actual CSS Classes in the priv/static/assets/app.css file, since it already knows the attributes. Something like:

# === core_components.ex ===
  def modal(assigns) do
    ~H"""
    <div
    [...]
      class="relative_late_hidden"
      # or "drlh", "nice_hidden_item" or a much better name than this
      # I am sure the Phoenix Core group will find a better name
    [...]
   """
end
# ===  priv/static/assets/app.css ===
.relative_late_hidden {    
  position: relative;
  z-index: 50;
  display: none;
}

This way we accomplish what the --no-tailwind parameter should do: Get rid of Tailwind, and at the same time, we still have references to the style, as the documentation says. Plus, if we need to change how a component looks, it already has a reference where to modify the component looks.

This is what my limited knowledge of Web Development+LiveView reaches. I hope it makes sense.

Best regards,

Greg.