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 <your-project-name>. 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.
We’re really cooking with gas now! To finish the form, we just need to add the <label> elements, <input> elements, and <button>. As we add them, let’s wrap each of our <label><input> pairs in a <div> so they stay together.
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 <input>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 <input>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 <input> will look like this:
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 <label>s above our <input>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 <div> 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 <label> 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.
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 <button>, we can see one in action.
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.
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 <form> 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 <input> classes.
As we can see, our <input> 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:
We’ve extracted our duplicate classes and left the rest. As we find ourselves building similar components, then we can extract more classes!
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!