Apr 8, 2019

Using Bulma and Sass in Phoenix

As a follow-up to the Bootstrap post from a couple of weeks ago, let’s see how we can go about installing Bulma with Phoenix. The process is very similar, but there are a few deviations, so I figured it was worth a short post.

Getting started

We’ll start off by creating a new Phoenix application and then look at how to go about getting Bulma installed.

mix phx.new bulma

Choose Y when asked to fetch and install dependencies. Now we’ll change into the application directory and create the database.

cd bulma
mix ecto.create

And with that we’re ready to tackle installing Bulma.

Installing Bulma

Just like with Bootstrap, we have the same three tasks to get Bulma up and running in Phoenix:

The Sass and Fontawesome installations are identical to what we did for Bootstrap, but I’ve repeated the steps within this post for convenience.

Installing Sass

Our first task is to install Sass. To do so we can use npm.

We’ll change into the assets directory, and then run the necessary npm commands.

cd assets
npm install --save-dev node-sass sass-loader

Once that is complete we can rename our .css file to .scss.

mv css/app.css css/app.scss

We now need to update app.js to point to the renamed file.

// We need to import the CSS so that webpack will load it.
// The MiniCssExtractPlugin is used to separate it out into
// its own CSS file.
import css from "../css/app.scss"

And finally we need to update webpack.config.js so that our Sass files get processed.

/assets/webpack.config.js …line 31
  test: /\.s?css$/,
  use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']

All we’ve done here is alter the test statement to match on both .css and .scss; and then in the use section we’ve added sass-loader.

We are now good to go with Sass. Onto Bulma!

Installing Bulma

While still in the assets directory:

npm install --save-dev bulma

We can remove phoenix.css as we won’t be using it anymore.

rm css/phoenix.css
touch css/_custom.scss

We’re also creating a custom.scss file which can be used to over-ride the Bulma defaults. For instance to make sure Bulma is working we’ll throw the box class onto our main page in a later step, let’s update custom.scss so that the box has a pink background.

$box-background-color: #ffb3b3;

The final step is to import our custom file and the Bulma scss files in app.scss.

I’ve seen some conflicting information about what needs to go in your main scss file. I’ve found things work fine for me by simply importing my custom file and bulma, i.e.

/* This file is for your main application css. */

@import 'custom';
@import 'bulma';

However I’ve seen instructions indicating that for the custom file to have an affect we need to first import the initial-variables and functions files, then our custom file, and then finally the main bulma file. This would result in:

/* This file is for your main application css. */

@import 'initial-variables';
@import 'functions';
@import 'custom';
@import 'bulma';

I haven’t found the above necessary, but if you run into issues, you might want to give it a try.

Note that we can also import only the parts of Bulma we need. For instance instead of importing all of Bulma via @import 'bulma' we could do something like:

/* This file is for your main application css. */

@import 'custom';
@import 'button';
@import 'container';
@import 'form';

In anycase we’ll now add icon support via Fontawesome in the same way we did with Bootstrap.

Installing Fontawesome

I generally tend to use the Fontawesome CDN and this is the approach we’ll take here as well. This means all we need to do is update our application header to include the CDN link.

<!DOCTYPE html>
<html lang="en">
    <meta charset="utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>Bulma · Phoenix Framework</title>
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
    <link rel="stylesheet" href="<%= Routes.static_path(@conn, "/css/app.css") %>"/>

And that’s it, we’re ready for a test run.

Testing it out

Let’s navigate to the root directory and fire up the server.

cd ..
mix phx.server

If we navigate to http://localhost:4000/ we’ll see our beautiful home page!

Or not!

Now that we are using Bulma we’ll need to use Bulma classes to make our HTML look good. I won’t go over re-styling the default Phoenix homepage, but just to make sure Bulma is working let’s replace the phx-hero class with the Bulma box class.

<section class="box">
  <h1><%= gettext "Welcome to %{name}!", name: "Phoenix" %></h1>

Perfect, the box element appears and as per our custom stylesheet, it has a pink background.

We should also change the main wrapper in our layout. We want to swap out <main role="main" class="container"> with <main role="main" class="section">. This ensures we have some default margins around our content. We also need to swap out the flash sections so they are Bulma compatible.

<main role="main" class="section">
  <%= unless is_nil(get_flash(@conn, :info)) do %>
    <div class="notification is-info" role="alert"><%= get_flash(@conn, :info) %></div>
  <% end %>
  <%= unless is_nil(get_flash(@conn, :error)) do %>
    <div class="notification is-danger" role="alert"><%= get_flash(@conn, :error) %></div>
  <% end %>
  <%= render @view_module, @view_template, assigns %>

So that wraps things up. Just like Bootstrap, by default our forms are not going to look good out of the box, i.e.

Just like with Bootstrap, you’ll want to create some custom form helpers.


This was largely a rehash of Using Bootstrap and Sass in Phoenix but there are a few differences in getting Bulma set-up. Hopefully you’ll find this post helpful if you decide to go with Bulma as your CSS framework.

I haven’t played around with Bulma too much myself as of yet, but the little bit of exploration I have done has me pretty excited. I’m hoping to delve further into it in the near future…

Thanks for reading and I hope you enjoyed the post!

Comment on this post!