Learn Tailwind CSS - A Beginner's Guide
This is a beginner-friendly guide to using Tailwind CSS, a relatively new but immensely popular and likely game-changing CSS framework. Tailwind adopts a utility-first approach which makes it easy to customize and even easier to maintain as a project’s CSS grows in size.
CSS itself is difficult to manage in large projects and this is further exacerbated by traditional CSS frameworks, like Bootstrap, Foundation, and others which come with a long library of predefined components for common items like buttons, nav bars, footers, and so on. In short, CSS quickly becomes a mess: hard to write, hard to reason about, and even harder to update.
Tailwind solves many of these challenges by taking a lower-level approach: providing CSS helper classes that can be used to create and customize any design. It’s best to see this in action though by giving Tailwind a spin yourself.
Unfortunately, installing Tailwind CSS can be quite challenging as the official guide makes clear. While you might need all the bells and whistles for a full-fledged project, most of Tailwind can be used via a CDN and a single HTML file. This guide starts off showing how to use the CDN approach, then moves on to the full Node and everything else option after that.
Table of Contents
Tailwind Play
The simplest way to try out Tailwind is to use its interactive web browser mode over on Tailwind Play. This allows for updates to an existing HTML page and visualizes the changes. It’s a great first step along with the Tailwind docs to try out various features and the general Tailwind approach.
CDN
The second easiest approach–and the one I’d recommend starting with–is to use Tailwind CDN in a single HTML file. That way you have full control and can mimic a real-world development experience.
To start, create a new folder called tailwind-cdn
and navigate into it. Then create a file called index.html
.
$ mkdir tailwind-cdn
$ touch index.html
Let’s begin with a basic HTML5 template that will just have a div, a headline, and some paragraph text.
<!-- index.html -->
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<div class="container">
<h1>Hello, Tailwind!</h1>
<p>Let's learn how to use this new CSS framework.</p>
</div>
</body>
</html>
From your command line, since you are in the tailwind-cdn
folder, you can open this file in a web browser actually. So do that!
$ open index.html
To add the Tailwind CDN all we have to do is update our <head>
section with the following line:
<link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
Here is what the complete updated index.html
file should look like.
<!-- index.html -->
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<h1>Hello, Tailwind!</h1>
<p>Let's learn how to use this new CSS framework.</p>
</div>
</body>
</html>
If you save the file changes and refresh your web browser you’ll see that all formatting was stripped.
Our text is pretty cramped on the current webpage, no? It would be nice to add some margin padding horizontally to the sides of our text and vertically in between the text itself.
To add side padding to our existing <div class="container">
we merely add the class mx-5
so it becomes <div class="container mx-5">
:
m
stands for marginx
means apply to the x-axis5
represents the relative unit length which is rem for Tailwind
The same logic applies for adding vertical padding to the text within the <p>
tags which becomes <p class="my-5">
, albeit using y
for the y-axis instead of x
for the x-axis.
<!-- index.html -->
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
</head>
<body>
<div class="container mx-5">
<h1>Hello, Tailwind!</h1>
<p class="my-5">Let's learn how to use this new CSS framework.</p>
</div>
</body>
</html>
Refresh your web page again and you’ll see both the horizontal and vertical margins now added.
Let’s continue on by using Tailwind CSS to update the font for our <h1>
text. To control the size, we’ll add text-2xl
and to make the font bold we’ll add font-bold
. The updated class is therefore: <h1 class="text-2xl font-bold">
Here is the complete code:
<!-- index.html -->
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
</head>
<body>
<div class="container mx-5">
<h1 class="text-2xl font-bold">Hello, Tailwind!</h1>
<p class="my-5">Let's learn how to use this new CSS framework.</p>
</div>
</body>
</html>
Refresh your webpage again and you’ll see the changes in action.
One more example to demonstrate Tailwind CSS in action is around styling buttons. In our case, let’s add a “Sign up here!” button in blue that turns darker blue upon over. The code looks like this:
<!-- index.html -->
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
</head>
<body>
<div class="container mx-5">
<h1 class="text-2xl font-bold">Hello, Tailwind!</h1>
<p class="my-5">Let's learn how to use this new CSS framework.</p>
<button class="text-white font-bold bg-blue-600 hover:bg-blue-800 py-2 px-4 rounded">
Button!
</button>
</div>
</body>
</html>
In order Tailwind is doing the following:
text-white
sets the font text to whitefont-bold
sets the font to boldbg-blue-600
sets the background color to blue with the 600 shadehover:bg-blue-800
sets the hover background color to darker blue (800)py-2
sets the vertical padding (py
) to2
remspx-4
sets the horizontal paddingpx
) to4
remsrounded
makes the button edges rounded
Save your changes and refresh the webpage to see the changes in action:
And voila! A lightning fast introduction to Tailwind and a taste for its new approach to writing CSS.
The CDN option is a great way to get started but it has some limitations as noted in the docs. The recommended approach is to use Tailwind as a PostCSS plugin to take advantage of all its features. We’ll cover that in the next section.
PostCSS Plugin
Tailwind CSS is ultimately a PostCSS plugin so to get the most of out Tailwind in terms of features and performance, it should be run as such. Doing so requires a little more setup than using a CDN but it’s very doable. Tailwind creator Adam Wathan released a YouToube series in 2019 on this setup. These notes have a few updates but largely mimic his presentation.
Note: You’ll need to install npm if you haven’t already on your local computer.
To start, create a new directory on your computer and enter into it. I’ve decided to call mine tailwind-fun
.
$ mkdir tailwind-fun
$ cd tailwind-fun
The first step is to create a basic package.json
file, which can be done with following command from your Terminal:
$ npm init -y
My resulting file looks as follows:
// package.json
{
"name": "wailwind-fun",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
Next, install tailwindcss
as well as some tools to help process CSS through a chain of PostCSS plugins including postcss
itself, postcss-cli
, and autoprefixer
which automatically adds vendor plugins to your CSS prefixes.
$ npm install tailwindcss postcss postcss-cli autoprefixer
Look inside your package.json
file which now has a new dependencies
section with these plugins. A package-lock.json
file has also been created for the first time but you don’t need to inspect it.
// package.json
{
"name": "tailwind-fun",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"autoprefixer": "^10.0.2",
"postcss": "^8.1.10",
"postcss-cli": "^8.3.0",
"tailwindcss": "^2.0.1"
}
}
In order to customize Tailwind later on, we’ll need a tailwind.config.js
file which can be created with the following command:
$ npx tailwind init
Here’s the resulting file:
// tailwind.config.js
module.exports = {
purge: [],
darkMode: false, // or 'media' or 'class'
theme: {
extend: {},
},
variants: {
extend: {},
},
plugins: [],
}
Next, create a postcss.config.js
file in your root directory (aka within tailwind-fun
in this cas) to specify what PostCSS plugins to use. Currently, our two plugins are tailwindcss
and autoprefixer
.
// postcss.config.js
module.exports = {
plugins: [
require('tailwindcss'),
require('autoprefixer'),
]
}
Tailwind works by looking through a CSS file for custom markers and replacing them with Tailwind’s generated code. Create a new CSS file called tailwind.css
within a new css
folder.
$ mkdir css
$ touch css/tailwind.css
Then within the file, add three directives for base
, components
, and utilities
. When our CSS is compiled through PostCSS, Tailwind will find each and replace them accordingly with Tailwind code. We’ll see what this means in a moment.
/* css/tailwind.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
The last step before building Tailwind is we need a simple script to process our CSS through PostCSS plugins. In the existing package.json
file, add a build
script that uses postcss-cli
, takes css/tailwind.css
as its input file, and specifies output to a new file called public/build/tailwind.css
.
// package.json
{
"name": "tailwind-fun",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "postcss css/tailwind.css -o public/build/tailwind.css"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"autoprefixer": "^10.0.2",
"postcss": "^8.1.10",
"postcss-cli": "^8.3.0",
"tailwindcss": "^2.0.1"
}
}
Now build it! On the command line run npm run build
!
$ npm run build
A newly generated CSS file processed through PostCSS is now available in our output location. Open up the file located at public/build/tailwind.css
and take a look.
This is a long, long file populated by the three directives–base
, components
, and utilities
–referenced in the tailwind.css
file.
To look at what base
provided, look at the top of the file which includes modern-normalize
, a set of resets to try to normalize how all web browsers display CSS. The first 540 or so lines comes from base
and are global resets.
If you scroll down to line 549 we see a .container
class, the solo component class injected into CSS wherever we added @tailwind components
. After the container
class there are a bunch classes like appearance-none
, bg-fixed
, etc which are simple utility classes added wherever the @tailwind utilities
directive was found. Note that appearance-none
has vendor prefixed properties such as webkit-appearance
and -moz-appearance
, which were added by autoprefixer
.
With this machinery in place, let’s create a simple HTML file and finally use Tailwind properly! Create a simple HTML file called index.html
within the public/
folder.
$ touch public/index.html
Then fill out a basic HTML template similar to what we had in the CDN section. The only change is that we’re importing tailwind.css
from the build
folder, rather than via a CDN.
<!-- public/index.html -->
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="/build/tailwind.css" rel="stylesheet">
</head>
<body>
<div class="container mx-5">
<h1 class="text-2xl font-bold">Hello, Tailwind!</h1>
<p class="my-5">Let's learn how to use this new CSS framework.</p>
<button class="text-white font-bold bg-blue-600 hover:bg-blue-800 py-2 px-4 rounded">
Button!
</button>
</div>
</body>
</html>
A nice tool to automatically reload our browser based on text changes is called live-server. It is lightweight and can be installed globally as follows:
$ npm install -g live-server
Then point it at our public
folder:
$ live-server public
This will bring up http://127.0.0.1:8080 in your web browser where we can see the same basic text and styling as we had in the previous section. This confirms the installation of Tailwind is working!
Conclusion
This guide is still in-progress but I hope the setup instructions helps anyone looking to learn more about Tailwind. I’ll add more content as time allows.
Note that since Tailwind does not come with a design in-and-of-itself, many developers reach for Tailwind UI, a set of paid pre-made UI components that can be added to a website if you aren’t a designer yourself.