Mix tailwind - 4.0.0-beta.1 support

I thought I’d try to install tailwind 4.0.0-beta.1 (Release v4.0.0-beta.1 · tailwindlabs/tailwindcss · GitHub) that was released today and see how far I got.
Tailwind 4 has some big changes so I don’t expect this to work out-of-the box without any work, but I thought I’d try and see how far I get.

so, I changed the config to

config :tailwind,
  version: "4.0.0-beta.1",

and did a mix tailwind.install, changed the css file according to Tailwind CSS v4.0 Beta - Tailwind CSS
and everything seems to run fine, but I don’t get my classes detected.

If I run _build/tailwind-linux-x64 -i assets/css/app.css -o test.css directly, the css file is correct, so it must be something with the arguments that’s different (I think).

Will play a little bit more around and see if I can get it working completely.

7 Likes

Got it working:

This is a working config:

  version: "4.0.0-beta.1",
  default: [
    args: ~w(
      --input=assets/css/app.css
      --output=./priv/static/assets/app.css
    ),
    cd: Path.expand("../", __DIR__)
  ]

diff:

As you can see, the difference is to not cd into assets. Tailwind 4 does source detection differently, but you can still configure it: Tailwind CSS v4.0 Beta - Tailwind CSS, so the old configuration can probably be kept with correct source detection, but I didn’t bother with that.

10 Likes

also work with custom class like min-w-[200px] with this new source code detection?

1 Like

I don’t see why this would not work?

1 Like

I’ve been using the alpha for a few months, and I prefer using the new configuration in the app.css file and deleting the js config. I did not change the config.exs, so it still does the cd into the assets directory.

config :tailwind,
  version: "4.0.0-beta.1",
  my_app: [
    args: ~w(
      --input=css/app.css
      --output=../priv/static/assets/app.css
    ),
    cd: Path.expand("../assets", __DIR__)
  ]
/* if you want dark mode via class */
/* default is to use prefers-color-scheme */
@variant dark (&:where(.dark, .dark *));

@variant phx-click-loading (.phx-click-loading&, .phx-click-loading &);
@variant phx-submit-loading (.phx-submit-loading&, .phx-submit-loading &);
@variant phx-change-loading (.phx-change-loading&, .phx-change-loading &);

@plugin "./heroicons.tailwind.plugin.js";

@source "../js/**/*.js";
@source "../../lib/my_app_web.ex";
@source "../../lib/my_app_web/**/*.*ex";

@import "tailwindcss";

And create a heroicons.tailwind.plugin.js if you use heroicons:

const fs = require("fs");
const path = require("path");

module.exports = function ({ matchComponents, theme }) {
  let iconsDir = path.join(process.cwd(), "../deps/heroicons/optimized");
  let values = {};
  let icons = [
    ["", "/24/outline"],
    ["-solid", "/24/solid"],
    ["-mini", "/20/solid"],
    ["-micro", "/16/solid"],
  ];
  icons.forEach(([suffix, dir]) => {
    fs.readdirSync(path.join(iconsDir, dir)).forEach((file) => {
      let name = path.basename(file, ".svg") + suffix;
      values[name] = { name, fullPath: path.join(iconsDir, dir, file) };
    });
  });
  matchComponents(
    {
      hero: ({ name, fullPath }) => {
        let content = fs
          .readFileSync(fullPath)
          .toString()
          .replace(/\r?\n|\r/g, "");
        let size = theme("spacing.6");
        if (name.endsWith("-mini")) {
          size = theme("spacing.5");
        } else if (name.endsWith("-micro")) {
          size = theme("spacing.4");
        }
        return {
          [`--hero-${name}`]: `url('data:image/svg+xml;utf8,${content}')`,
          "-webkit-mask": `var(--hero-${name})`,
          mask: `var(--hero-${name})`,
          "mask-repeat": "no-repeat",
          "background-color": "currentColor",
          "vertical-align": "middle",
          display: "inline-block",
          width: size,
          height: size,
        };
      },
    },
    { values },
  );
};

I think v4 is a fantastic advancement. It uses native CSS layers, which I find solves all problems I have with using selectors for the base style of components, while still allowing the use of utility classes for overrides.

26 Likes

Does this go into app.css ?
Additionally - do we need @source ?

Yes and yes. It’s possible they may add automatic detection logic specifically for the structure of Phoenix, but even if they do that, I prefer being explicit about sources to avoid ever having a problem.

1 Like

Thanks a lot. I guess that @source part is not yet working in phoenix application. Once I added that, it started working.

As a follow-up, here’s a gist with a simple & robust implementation of dark mode toggling. It contains the config to add to app.css, and button and JS components to add to your core_components.ex file.

5 Likes

I gave the tailwind 4 beta a try…
But the layout looks so different compared to V3

As far as I understood @theme should overwrite the defaults like extend does
in the tailwind.config.js file for V3

With this in my app.css file:

/* TAILWINDCSS BETA 4 app.css */
/* @variant dark (&:where(.dark, .dark *)); */

@variant phx-click-loading (.phx-click-loading&, .phx-click-loading &);
@variant phx-submit-loading (.phx-submit-loading&, .phx-submit-loading &);
@variant phx-change-loading (.phx-change-loading&, .phx-change-loading &);

@plugin "../heroicons.tailwind.plugin.js";

@source "../js/**/*.js";
@source "../../lib/*_web.ex";
@source "../../lib/*_web/**/*.*ex";

@import 'tailwindcss';

/* moved from tailwind.config.js */
@theme {
  --breakpoint-fullscreen: '1920px';
  --breakpoint-3xl: '1680px';

  --font-brand: "Gloria Hallelujah";
}

it looks like I have no lg: media selector or any other at all…

I tried to find some information over at tailwind but github discussion and discord is a mess (at least for me)

Where do I have to look at/search for?

I am aware that this is a beta and V3 does the job

Was just curious and wanted to test some of the new features
Best regards

everything worked except that tailwind auto suggest is not working. Did you face the same problem @frankdugan3 ?

No, it’s working for me, but I’m using a custom Neovim config. Whatever editor you’re using, double-check all your tailwind plugins are updated. Also double-check the required config for the plugin(s) haven’t changed with v4.

Just for reference, the following guide worked better for me:

1 Like

How!? on a fresh phoenix app? with heroicons etc?

Here’s gist that covers it all together: Phoenix Tailwind v4 · GitHub

3 Likes

Yea, but the guy said that official doc works for him, and I’m curious how it is possible :slight_smile:

Anyone who knows if there is an effort for making Tailwind Merge for version 4?
The two existing libraries are deprecated.

Have a look at this issue:

I dont think they mention anything about a Tailwind Merge package?

Oh… Yes…
My fault. Sorry

1 Like