If you’ve been staying in the loop with the latest CSS frameworks, you’ve probably already heard of the newest kid on the block: Tailwind CSS. According to its documentation, “Tailwind is a utility-first CSS framework for rapidly building custom user interfaces.”

In practice, this means using a variety of classes that closely map to underlying CSS properties. For example, applying a class like .text-center to an element means that we’re setting its text-align property to center. Simple enough, right?

Using utility classes like this allows us to spend more time iterating through designs and avoiding premature abstraction of our CSS. Then, once we’re happy with our designs, Tailwind makes it easy to extract our utilities into component classes.

Now, I’m sure you know that even mentioning a utility framework is an open invitation for a certain amount of brouhaha. Before we start yelling at me on Twitter or the comments for even mentioning a utility framework, let’s just take a moment to remember that Tailwind is just one possible tool for us to use.

If you don’t want to add it to your toolbox, then no worries—you do you! But, if you’re interested in at least understanding this new tool, let’s take a look at building a sign-up form together.

Without further ado, let’s set up a fresh project with Tailwind, code out some HTML, and style it up.

The Set Up

Let’s start by creating a directory for us to work from. Using your terminal, navigate to the directory you’d like to create your project and run mkdir . Now, let’s cd into our new project and follow the Tailwind installation guide.

Since we want to see everything that Tailwind can do, let’s install it with npm or Yarn using the following.

# Using npm
npm install tailwindcss --save-dev

# Using Yarn
yarn add tailwindcss --dev

With Tailwind installed, we can now generate the configuration file by running ./node_modules/.bin/tailwind init. This generates a tailwind.js file for us in the root of our project. In this file, we can adjust Tailwind’s default settings to our project’s needs. For this project, we shouldn’t have to change a thing.

Now, let’s create a CSS file where we can manage our own CSS and inject the Tailwind styles. To do that we can run touch styles.css from our project directory.

Inside of this new file, we can use Tailwind’s @tailwind directive to inject the preflight and utilities styles into our CSS. preflight contains all of the base styles and some browser style normalizations, while utilities adds all of the utility classes we specified in our config file. So, our styles.css file should look something like this:

@tailwind preflight;

/* Here we can add any custom overrides */

@tailwind utilities;

/* Here we can add our own utilities or custom CSS */

If you’re using PHPStorm and you’re annoyed by the red squiggles in your CSS file for @tailwind, just add /*noinspection CssInvalidAtRule*/ above where you use it.

With that all set up, we can run ./node_modules/.bin/tailwind build styles.css to generate the CSS file we’d like to use in our project. This may seem a bit tedious, but don’t worry! Tailwind works with proper build tools like Webpack, Gulp, or Laravel Mix, so in a larger project you can just set it and forget it.

That’ll take care of our Tailwind set up! Now, we can start coding our HTML.


Before we can style our sign-up form, we need to build it! To start, we’ll need a simple index.html file. So, from your root directory, you can run touch index.html to create the file. Then, we can add the following snippet to get us started.

  Tailwind Intro

As you can see, it’s your typical HTML page. The only wrinkle here is that we’re importing our main.css file and we’ve given our page a descriptive title. Now, let’s start building our sign-up form!

To start, let’s add two nested

elements to the inside of our tag.


We’ll use the outer

for our page positioning, while the inner

will be the wrapper for our form. Now, inside the inner

, we can add a

to label the form, and a


Sign Up

We’re really cooking with gas now! To finish the form, we just need to add the elements, elements, and

Finally, let’s add a link to access the login page right below our form.

Putting that all together, our HTML will look like this:

  Tailwind Intro


Sign Up

Already have an account?

Pretty straightforward, right? Now, when we see how that renders on the page, we should see something that looks like this:

Don’t be alarmed if it looks like the s are missing; that’s just the browser resets at work. At last, we’re ready to see what this Tailwind CSS is all about.

Using Tailwind CSS

Being the good developers that we are, let’s take a mobile-first approach to styling our sign-up form. So, at a smaller viewport width of 400px, our page looks like this:

Styling Our Form Fields

Let’s start using Tailwind by styling our s. First, let’s add a border so we can see it on the page. To do that, we just need to add the .border class. So, now our first name will look like this:

Now we can see it on the screen!

How easy was that? Let’s continue by adding some padding and making the text color a touch lighter. To do that, we just need to add the following classes: .py-2, .px-3, and .text-grey-darkest.

With the first two classes, we’re taking advantage of the padding scale that comes with Tailwind and applying it vertically and horizontally to the element. If you want to define your own scale, just hop into your config file and change it to what you need. With the last class, we’re using Tailwind’s default color palette and changing the color of our element to the darkest grey.

Let’s take our form a step further. Now, we can position our s above our s and give them a bit of styling.

Look at that, our first name field looks great! And the best part is that I really don’t have to explain what these classes are doing—they explain themselves! But just so we’re all on the same page, let me run through them quickly.

The outer

has its display property set to flexvia .flex and its flex-direction is set to column with .flex-col. Then it has a bit of margin on the bottom thanks to .mb-4.

Meanwhile, our has a little less margin on the bottom thanks to .mb-2. The rest of the classes make our text uppercased, bold, large (1.125rem), and the darkest grey in our color palette.

Altogether, a pretty quick and easy way to style our fields! Now, let’s add these styles to the rest of our fields, style our button and link, and see what we’re working with.

Already have an account?

Adding Hover Styles

Now things are starting to look better! In this block of code, everything should be pretty self-explanatory. However, we have added one new thing: a state variant. If we take a look at our

If you look at the class right after .bg-teal, you can see that we’ve added a hover: prefix to .bg-teal-dark. These prefixes let us style elements on hover and focus, and they let us use breakpoints too! All in all, this is a pretty powerful feature of Tailwind and it lets us create dynamic, responsive UI very quickly.

Now, let’s wrap our mobile view by positioning our form in the middle of the screen and adding a colorful page background.

Sign Up

Already have an account?

Bada bing bada boom, we’ve got ourselves a good-looking mobile sign-up form! But, what happens when we take a look at this on a bigger screen?

Responsive Design

It’s certainly better than our plain HTML, but it needs some work. Let’s use some of the responsive state variants and style this for larger screens.

Sign Up

Already have an account?

Thanks to our responsive prefixes, our sign-up form is looking much better! Let’s take a look at our

for some examples.


Just like with our hover: prefix, we’re only applying the prefixed classes when that condition is met. In this case, that means we’re only applying the flex styles to our

when the page’s min-width is 768px.

Extracting Utilities Into Components

Now that we’ve finished prototyping our form, we can extract our utility classes into component classes. Let’s start by extracting our classes.

As we can see, our has a couple of classes on it. We can extract these to our CSS using Tailwind’s @apply directive. @apply allows us to apply the same styles that our utility classes use to a new class. So, at the bottom of our styles.css file, we can add the following:

.field {
  @apply .border .py-2 .px-3 .text-grey-darkest;

Then, once we’ve re-complied our Tailwind files, our can just have the .field class.

As you can see, with Tailwind we get the best of utility and component classes! We can iterate quickly with utility classes, and still extract component classes when we start to see a pattern.

Even better, we can blend them to handle those one-off cases where dedicated component classes don’t make sense.

The Final CSS

Applying this thinking to the rest of our code, our CSS and HTML will look like this.

@tailwind preflight;

/* Here we can add any custom overrides */

@tailwind utilities;

/* Here we can add our own utilities or custom CSS */

.field {
  @apply .border .py-2 .px-3 .text-grey-darkest;

.field-label {
  @apply .uppercase .font-bold .text-lg .text-grey-darkest .mb-2;

.field-group {
  @apply .flex .flex-col;

.btn {
  @apply .block .text-white .uppercase .text-lg .p-4 .rounded;

.btn-teal {
  @apply .bg-teal;

.btn-teal:hover {
  @apply .bg-teal-dark;

.link {
  @apply .block .no-underline .text-sm;

.link-grey {
  @apply .text-grey-dark;

.link-grey:hover {
  @apply .text-grey-darker;

The Final HTML

  Tailwind Intro


Sign Up

Already have an account?

We’ve extracted our duplicate classes and left the rest. As we find ourselves building similar components, then we can extract more classes!

Wrap Up

Whew! We certainly covered a lot in this post. We started out stretching our HTML muscles by building a quick form, and then we took a mobile-first approach to our styles with Tailwind. Along the way, we saw how to use Tailwind’s utility classes to quickly style an element. Then, we used state variants to add some dynamic styles. And finally, we saw how we could have our cake and eat too when we extracted our duplicate classes to component classes.

I hope that you were able to get a taste of how Tailwind can make an impact in your own projects. If you’d like to mess around with this project, feel free to clone the repo and experiment with Tailwind yourself. As always, feel free to ask me any questions on Twitter. And until next time, happy coding!

How to Style a Form With Tailwind CSS is a post from CSS-Tricks