Awesome
<div align="center">Learn
Tailwind CSS
to craft
pixel-perfect
beautifully adaptive
web apps/sites
in less time.
Use these links to skip stright to the section that interests you:
Why?
Many people consider
CSS
difficult.
Plenty of memes: google.com/search?q=css+meme
We think everyone building web apps/sites
should learn CSS
. <br />
However we agree that it can feel frustrating
and often overwhelming. <br />
Many software engineers/developers
feel they already have enough to learn
with the rest of their chosen
"stack",
so investing the time
to perfect the interface design & layout
feels like too much.
We get it!
Learning Tailwind
will not mean
you don't need to learn/understand CSS
.
But it will make it
a lot easier.
We think the infamy of
CSS
is unjustified. Like learning how to juggle, you will get hit in the face by a few stray objects in your quest to learnCSS
. If you invest the time to learnCSS
from first principals, you will have the skills to avoid the frustration. As with most things, it's usually just a matter of making the time to learn/understand it.
Why Switch to Tailwind
?
We have not taken the decision to switch our UI library lightly. As with all technology decisions, we must weigh the pros & cons carefully because there is a substantial time investment required.
We felt (still feel) that the benefits of switching (outlined below) justify the cost - learning time, updating code & maintenance.
We encourage you to read through this doc
and make up your own mind
if Tailwind
is a good fit
for you and your team/project.
What?
Tailwind
CSS
is a utility-first CSS framework
that can be composed to build any design,
directly in your markup. ~
tailwindcss.com
💡 Tip: Read through the
Tailwind
landing page, it summarises the benefits very well.
In-line styles
directly in a UI element
so you never have to hunt
for a style definition across multiple files.
It means you don't suffer
the change-one thing
breaks many others pain
of traditional CSS
.
This is a huge time saver even in a modest sized project.
Top 10 Reasons We Love Tailwind
- Declarative utility focussed
CSS
classes that allow you to locally scope all presentation and avoid polluting the global space. - Logical numeric property increments
mean it's immediately obvious from reading
the
class
bg-red-500
#ef4444
in yourHTML
that the background is red and the intensity is500
(on the scale 0-1000) and therefore logically the "hover background red 700"hover:bg-red-700
#b91c1c
is a deeper red. See: Colors section below. - Flexible function-like class names
let you define precise values for attributes
like
position
,padding
,margin
e.g:m-[5px]
orm-[2%]
when you need a very specific pixel dimension or a specific percentage. see: tailwindcss.com/docs/margin#arbitrary-values This is a huge improvement over being stuck with pre-defined values! Consider this compound class to create a gradient: <br />bg-gradient-to-r from-green-400 to-blue-500
<br /> <br /> Even a complete beginner can infer what these 3 classes are doing: <br /> "Background gradient to right, from green level 400#4ade80
, to blue level 500#0ea5e9
". <br />Note: Obvs we don't do this in practice, but it shows the power! 🌈
- Superb visual documentation with easy two-way search;
lookup the
CSS
attirbute orTailwind
class with auto-completion makes finding what you need very fast! - Built-in pre-processor bundles
and minimises your styles
so you never ship bloated
CSS
again; especially important for larger projects. - Actively developed by the original author
who is
working full-time
and still passionate about the project,
see:
What's New in
Tailwind
v3.1 where the creator Adam Wathan summarises recent improvements. - Thriving community with many contributors and frequent improvements, see: github.com/tailwindlabs/tailwindcss
- UI Library [not free but very reasonably priced!] which means there is a sustainable business model i.e: it wont cease to be maintained because the creator is getting paid to do it full-time.
- Free complete themes, UI components/kits & resources to kick-start your project. e.g: tailwindtoolbox.com
- Please add yours here!! 🙏
!important
Tailwind
Eliminates the "Cascade"
One of the most amazing and powerful features
of CSS
("Cascading Style Sheets")
is also one of the greatest sources
of frustration when using it in practice.
When you have a "cascade",
styles can be applied globally
to your web site/app
and thus you only have to change
things in one place
for them to take effect everwhere.
In practice this only works when
everyone editing the CSS
is reasonably proficient
and there is a clear system
for making the changes.
When all styles are globally scoped,
making fine adjustments to the position
of a particular UI element becomes tedious
which leads to spagheti code
full of specificity headaches.
If you see the word
!important
in CSS
you know that
people have given up
on the maintainability.
What about Tachyons
?
@dwyl
we've been using
Taychyons
(Functional CSS Library)
for the past 5 years
and (as always)
comprehensively
documented our learning in
dwyl/learn-tachyons
and
dwyl/tachyons-bootstrap. <br />
Tachyons
preceeds Tailwind
by 3 years - inital release 2014 vs. 2017 -
so you could even say that one inspired
or layed the
groundwork
for the other.
We still ❤️ Tachyons
and will use it where it makes sense.
Tachyons
is lightweight (14kb
)
and has very similar utility classes to Tailwind
;
we consider the two almost interchangeable.
We won't be updating any of the projects that use Tachyons
to use Tailwind
because none of them are "broken",
require zero maintenance and work well as-is!
The key diference is
approach taken to building the library.
Tachyons
is just the CSS
(which is great for anywhere
you don't want to have
build pipeline/process)
whereas Tailwind
is a JavaScript
library
that includes parser/pre-processor.
The advantage of having a JS
library
means you can create your own
Functions, Components and Directives
that are immensely powerful
and offer significant flexibility.
JS
means you are forced
to have a build step in your dev/deployment pipeline
to use Tailwind
.
However, given that Tailwind
works with
esbuild
(which is very fast and reliable
and already included with Phoenix
)
we feel that the trade-off is worth it.
With Tailwind
we get the
"best of both worlds",
we get a utility-first CSS library,
that also has the flexibility/power
of a customizable design system.
What about XYZ
Framework?
There is a virtually endless list
of CSS
frameworks,
component libraries and pre-processors available. <br />
see:
github.com/troxler/awesome-css-frameworks
... <br />
For a good comparison
read:
athemes.com/collections/best-css-frameworks
or
dev.to/samlan/best-css-frameworks-for-2022-1afm
Ultimately for us,
we did our own research into the available alternatives
but kept an open mind.
We were
guided
by the
Elixir
/ Phoenix
community toward Tailwind
and we have not been disapointed.
Tailwind
in Phoenix
As of Phoenix 1.7
,
Tailwind
is now included by default
.
We
called it
last year.
And we're delighted our investment payed off!
Who?
This guide is aimed at anyone that:
A. Wants to evaluate Tailwind
for themselves
or their team without the hype/noise. <br />
B. Needs to learn Tailwind
as fast as possible
but without skipping any steps! <br />
C. Has to summarise & share
their knowledge of Tailwind
with a team/community of people.
If you find this useful, please ⭐ on GitHub to let us and others know. Thanks! 🙏
How?
If you just want to test
Tailwind
with the least effort,
use the online playground:
play.tailwindcss.com
Speed-read through the docs: tailwindcss.com/docs/utility-first and try a changing a few values, e.g: start by changing solors names/levels.
Part 1: Try
Before You Commit
The official
get started guide
instructs you to perform several setup (installation) steps
before
you try the framework.
But you can skip these steps
if you just want to evaluate it.
Create index.html
Create an index.html
file
on your computer
with the following contents:
https://raw.githubusercontent.com/tailwindtoolbox/Admin-Template/master/index.html
Open the file in your web brower, you should see something similar to:
Once you've made a few changes
in the index.html
file
and seen the results
in your web browser,
you should have a decent idea
of the power of Tailwind
.
If you have a decent Internet connection and no bandwidth constraints, we recommend watching Designing with Tailwind CSS: The Utility-First Workflow: https://youtu.be/Ybybd3GCNn4
made by
Adam Wathan
@adamwathan
(Creator of Tailwind)
Colors!
We are huge fans of the numeric indexing of the built-in colors: https://tailwindcss.com/docs/customizing-colors
<br />Part 2: Tailwind
in Phoenix
To run the finished version of our
Tailwind
+ Phoenix
Demo,
run:
git clone git@github.com:dwyl/learn-tailwind.git && cd learn-tailwind
mix setup
mix phx.server
Build Log (How we got here)
Create a barebones Phoenix App:
mix phx.new app --no-mailer --no-dashboard --no-gettext --no-ecto
Install the dependencies. Then open the project in your editor.
Run the app:
mix phx.server
You should see output similar to the following in your terminal:
Generated app app
[info] Running AppWeb.Endpoint with cowboy 2.9.0 at 127.0.0.1:4000 (http)
[info] Access AppWeb.Endpoint at http://localhost:4000
[debug] Downloading esbuild from https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.29.tgz
[watch] build finished, watching for changes...
That's a good sign, esbuild
was downloaded
and the assets were compiled successfully.
Visit
localhost:4000
from your browser.
You should see something similar to the following
(default Phoenix
homepage):
That's nice. But a bit boring ... let's add some pizzazz! ✨
Open the mix.exs
file and add :tailwind
to defp deps
:
{:tailwind, "~> 0.1.9", runtime: Mix.env() == :dev},
Run:
mix deps.get
Once installed,
add the following lines to config/config.exs
to pick your tailwind version of choice:
config :tailwind,
version: "3.1.0",
default: [
args: ~w(
--config=tailwind.config.js
--input=css/app.css
--output=../priv/static/assets/app.css
),
cd: Path.expand("../assets", __DIR__)
]
Now you can install the library. Run the following commands in order.
mix tailwind.install
mix tailwind default
These commands will generate the
Tailwind CLI and
create a assets/tailwind.config.js
file.
They will also create an executable
inside _build/tailwind-TARGET
where TARGET is your target system architecture.
For development, we want to enable watch mode.
So find the watchers
section in config/dev.exs
and add:
tailwind: {Tailwind, :install_and_run, [:default, ~w(--watch)]}
Note: this enables the file system watcher.
Ensure that the import "../css/app.css"
line
is no longer in assets/js/app.js
(should have automatically been removed by adding Tailwind
...)
Finally, back in your mix.exs
,
make sure you have a assets.deploy
alias for deployments,
which will also use the --minify
option:
"assets.deploy": ["tailwind default --minify", "esbuild default --minify", "phx.digest"]
Open the lib/app_web/templates/page/index.html.heex
and replace the contents with:
<h1
class="text-7xl text-white font-bold text-center w-full bg-slate-800 rounded-xl shadow-lg py-3 mt-3 ml-3"
>
Hello TailWorld!
</h1>
Run the Phoenix
App:
mix phx.server
Visit localhost:4000
in your web browser:
Those semantic utility class names should give you a flavour for what to expect in the UI.
Fix the failing tests!
Open test/app_web/controllers/page_controller_test.exs
and change the assertion from:
assert html_response(conn, 200) =~ "Welcome to Phoenix!"
to:
assert html_response(conn, 200) =~ "Hello TailWorld!"
More Detailed Example!
We're using Tailwind
for our Phoenix LiveView
Chat Example:
https://github.com/dwyl/phoenix-liveview-chat-example
We think it's siiiiiiick! More examples to follow soon!
Petal Components
<img width="545" alt="petal.build" src="https://user-images.githubusercontent.com/194400/193780264-16a4330d-df64-4f04-9c89-2d6b1146ad32.png">Petal components are a set of reusable functions to help you build a nice UI:
Follow the instructions steps at https://petal.build/components to install the
Petal components to your Phoenix project. After that you'll be able to call in your
templates the components with the syntax <.component>...</.component>
, for example:
<.h2>Title</.h2>
see: