Rails 6.1 with TailwindCSS 2.0 and AlpineJS
Intro
TailwindCSS is a very flexible CSS framework and makes it easy to customize unique web pages and animations.
Unfortunately, with Rails its a bit tricky to install and configure with Rails Standards.
- TailwindCSS 2.0 expects PostCSS 8 and Rails Webpacker uses PostCSS 7 (for now)
- TailwindCSS 2.0 expects AlpineJS, React or Vue – by default Rails uses StimulusJS (although you can additionally install AlpineJS)
Rails Setup
I am assuming you have followed the Rails setup described at:
In the end, I feel like its easier / better to use tailwindcss with AlpineJS since that is how it evolved and lots of Internet resources are available for that.
Install Tailwind CSS 2.0
Tailwind CSS 2.0 Install
Start by installing the tailwindcss compatible with postcss7 (necessary until rails-webpacker updates to postcss8) – with or without upgrading webpacker the following should work:
yarn add tailwindcss@latest postcss@latest autoprefixer@latest
# if you get this error: Error: PostCSS plugin tailwindcss requires PostCSS 8. use:
# yarn add tailwindcss@npm:@tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9
now install AlpineJS (its easier to use AlpineJS with tailwind but Stimulus works too - just need to do it all yourself - alpine and stimulus play well together in Rails). Add alpine turbo drive adapter so that the AlpineJS effects work even AFTER clicking on a link!
yarn add alpinejs
yarn add alpine-turbo-drive-adapter
If you see something like:
arn add aplinejs
error An unexpected error occurred: “https://registry.yarnpkg.com/aplinejs: Not found”.
then check the spelling of the package(s).
Now create the tailwind config file
npx tailwindcss init
now config tailwind:
// tailwind.config.js
module.exports = {
purge: [
'./app/**/*/*.html.erb',
'./app/helpers/**/*/*.rb',
'./app/javascript/**/*/*.js',
'./app/javascript/**/*/*.vue',
'./app/javascript/**/*/*.react'
],
darkMode: false, // or 'media' or 'class'
theme: {
extend: {},
},
variants: {
extend: {},
},
plugins: [
// not needed here ?
// require('@tailwindcss/forms'),
],
}
tell postcss.config.js
about tailwind:
/* postcss.config.js */
module.exports = {
plugins: [
require("tailwindcss")("./tailwind.config.js"),
require("postcss-import"),
require("postcss-flexbugs-fixes"),
require("postcss-preset-env")({
autoprefixer: {
flexbox: "no-2009",
},
stage: 3,
}),
],
}
create application.scss
mkdir app/javascript/stylesheets
touch app/javascript/stylesheets/application.scss
cat <<EOF >app/javascript/stylesheets/application.scss
/* app/javascript/stylesheets/application.scss */
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
/* Add custom CSS here */
EOF
import tailwind into application.js
/* app/javascript/packs/application.js */
import Rails from "@rails/ujs"
import "@hotwired/turbo-rails"
import * as ActiveStorage from "@rails/activestorage"
import "channels"
// import alpinejs and its necessary rails adaptation
import 'alpine-turbo-drive-adapter'
require("alpinejs")
// import tailwind into javascript
import "../stylesheets/application.scss"
Rails.start()
ActiveStorage.start()
import "controllers"
require("trix")
require("@rails/actiontext")
It’s great to get samples from https://tailwindui.com (& other places) - USE THE INSPECTOR to copy the HTML (this will copy the AlpineJS settings too) - the standard copy HTML button requires you to add the JS on your own.
create a navbar:
touch app/views/layouts/_navbar.html.erb
cat <<EOF >app/views/layouts/_navbar.html.erb
<nav x-data="{ open: false }" class="bg-gray-800">
<!-- NavBar here -->
</nav>
EOF
Create a footer:
<!-- app/views/layouts/_footer.html.erb -->
<footer class="bg-gray-50" aria-labelledby="footerHeading">
<h2 id="footerHeading" class="sr-only">Company</h2>
<div class="max-w-md mx-auto pt-12 px-4 sm:max-w-7xl sm:px-6 lg:pt-16 lg:px-8">
<div class="xl:grid xl:grid-cols-3 xl:gap-8">
Some Footer Info
</div>
<div class="mt-12 border-t border-gray-200 py-8">
<p class="text-base text-gray-400 xl:text-center">
© 2020 Company, Inc. All rights reserved.
</p>
</div>
</div>
</footer>
Update the landing page:
<!-- app/views/landing/index.html.erb -->
<!-- landing page here -->
application.html.erb
needs to import the javascript stylesheet and the navbar
<!-- app/views/layouts/application.html.erb -->
<!DOCTYPE html>
<html>
<head>
<title>Vivers</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<link rel="stylesheet" href="https://rsms.me/inter/inter.css">
<%= stylesheet_link_tag 'application', media: 'all' %>
<%= stylesheet_pack_tag 'application', media: 'all' %>
<%= javascript_pack_tag 'application' %>
<%= yield :head %>
<%= turbo_include_tags %>
<%# stimulus_include_tags %>
</head>
<body>
<div>
<div class="pb-32">
<%= render 'layouts/navbar' %>
<header class="py-10">
<div class="max-w-9xl mx-auto px-4 sm:px-6 lg:px-8">
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
<h1 class="text-3xl font-bold">
Dashboard
</h1>
</div>
</header>
</div>
<main class="-mt-32">
<div class="max-w-9xl mx-auto pb-12 px-4 sm:px-6 lg:px-8">
<%= yield %>
</div>
</main>
<%= render 'layouts/footer' %>
</div>
</body>
</html>
You may need to want rails with both (to increase reload speed after changes – but bin/rails s
is enough):
bin/rails s
# runnding the following in a separate window tends to speed CSS / JS recompilation
./bin/webpack-dev-server
Install Tailwind SVG Icons
You can embed the Icon directly into the View - downloading from:
https://heroicons.dev/ https://heroicons.com/
However, you can also use a gem and add flexibility:
https://github.com/bharget/heroicon
In gemfile
gem "heroicon"
From CLI:
bundle
rails g heroicon:install
Usage:
<%= heroicon "search" %>
<%= heroicon "search", variant: :outline %>
<%= heroicon "search", options: { class: "text-primary-500" } %>
or https://github.com/andrewjmead/rails_heroicons/
Gemfile
gem 'rails_heroicons', '~> 1.0.1'
CLI
bundle
gem install rails_heroicons
Usage:
<%= heroicon('user') %>
<%= heroicon('user', class_name: 'icon icon-large') %>
<%= heroicon('user', style: :outline, class_name: 'icon icon-large') %>
The classes magically update the SVG embedded using:
USE SVG Images / Icons in Rails – HeroIcons or ZondIcons
Downloaded SVG images in Rails: https://heroicons.com/ https://heroicons.dev/ http://www.zondicons.com/icons.html
OR download the Icons and use the gem: https://github.com/jamesmartin/inline_svg
Gemfile:
gem 'inline_svg'
CLI:
bundle
gem install inline_svg
USAGE:
# Sprockets
inline_svg_tag(file_name, options={})
# Webpacker
inline_svg_pack_tag(file_name, options={})
OR without gem:
you can embed the SVG directly into rails using: https://dev.to/hslzr/using-inline-svgs-with-rails-3khb
Reference Articles
https://davidteren.medium.com/tailwindcss-2-0-with-rails-6-1-postcss-8-0-9645e235892d https://web-crunch.com/posts/how-to-install-tailwind-css-2-using-ruby-on-rails