November 8, 2019

Tailwind CSS & Phoenix

Tailwind CSS is a highly customizable, low-level CSS framework that gives you all of the building blocks you need to build bespoke designs without any annoying opinionated styles you have to fight to override.

I am no front-end developer by any stretch of imagination. Utility-first CSS framework thus looks quite interesting as it allows rather rapid composition of various elements. It also plays nicely with other CSS frameworks, so you can start using it without rewriting rest of your code. But This article is going to cover the green field Phoenix project wanting to use it.

I have found similar tutorials on the Internets, but they have been always missing something. Versions in time of writing are Elixir 1.9.1, Phoenix 1.4.1, Tailwind 1.1.2, Webpack 4.4.0.

Getting started


If you are starting from scratch, just create your Phoenix app with something like mix tailwind. You can skip installation of dependencies for now. Then install Tailwind and PostCSS:

cd assets
npm install tailwindcss --save-dev
npm install postcss-loader --save-dev

That will install both packages and also adds them to package.json. Next thing is to add Tailwind as a plugin to PostCSS. You can do it through postcss.config.js file.

// assets/postcss.config.js

module.exports = {
  plugins: [

Or, as Phoenix already ships with webpack, just modify webpack.config.js directly. Relevant is css rules section, which looks like

  test: /\.css$/,
    use: [MiniCssExtractPlugin.loader, 'css-loader']

we will add PostCSS like shown at the following snippet:

  test: /\.css$/,
  use: [
      loader: 'postcss-loader',
      options: {
        ident: 'postcss',
        plugins: [

Use Tailwind in your stylesheet

We can remove assets/css/phoenix.css as we replace assets/css/app.css with

@tailwind base;
@tailwind components;
@tailwind utilities;

Tailwind’s documentation suggests using @import instead @tailwind, but that didn’t work for me.

(Optional) Tailwind’s configuration

Tailwind supports tweaking of its behavior (for example changing look-and-feel of the standard theme) through configuration file. You can easily generate configuration file with

cd assets && npx tailwind init
# or npx tailwind init --full in case you want to see all default values

And that’s it, Tailwind should be working.

Example – flash messages

Let’s use Tailwind in your Application. Flash messages are currently displayed with the following code (lib/surveys_web/templates/layout/app.html.eex):

<p class="alert alert-info" role="alert"><%= get_flash(@conn, :info) %></p>
<p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p>

Let’s replace it with

<p class="alert bg-green-200 border border-green-300 text-green-900 px-4 py-3 rounded relative" role="alert"><%= get_flash(@conn, :info) %></p>
<p class="alert bg-red-200 border border-red-300 text-red-900 px-4 py-3 rounded relative" role="alert"><%= get_flash(@conn, :error) %></p>

We now see the empty alert boxes shown on the site. Let’s add CSS to hide them (assets/css/app.css):

.alert:empty { display: none; }

Subscribe to weekend long-read suggestions

You can access archive of all suggestions at /long-reads. You can also send your suggestions to

You can unsubscribe at any time by clicking the link in the footer of our emails. For information about our privacy practices, please check Privacy Policy (hosted by iubenda).

We use Mailchimp as our marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp's privacy practices here.