knoebber

knoebber

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?

Most Liked

D4no0

D4no0

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.

LostKobrakai

LostKobrakai

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.

Eiji

Eiji

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.

Last Post!

GregPhx

GregPhx

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.

Where Next?

Popular in Proposals: Ideas Top

hst337
Elixir compiler and language specification Purpose of the proposal Elixir language is in mature state and no breaking or heavy changes ar...
New
bamorim
Story behind Recently, I gave a talk on a meetup about improving performance of Phoenix applications and the example app was a LiveView ...
New
Flo0807
Hello everyone! Phoenix LiveView v0.18 introduced the special attributes :let, :for and :if. In addition to the :if special attribute, I...
New
dvartic
Would there be interest to implement a link/1 that gives to option to operate on other events? So I implemented a simple link/1 function...
New
victor23k
Hi all! I come with a proposal to create LiveViews inside the shadow DOM. At Doofinder, we have experience building embeddable LiveView a...
New
sezaru
When writing my code, I always find __MODULE__ very useful to use as alias of that module “inner dependencies”, ex: alias __MODULE__.{Im...
New
ffloyd
The Problem Currently, if I define a struct in the following way: defmodule MyStruct do # Both x and y will have the FIXED values unti...
New

Other popular topics Top

nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 44265 214
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New

We're in Beta

About us Mission Statement