Tailwind Css
Tailwind Css
In the world of CSS frameworks, the battle for the best approach to styling web applications
continues. Some choose CSS modules with SCSS or not, others prefer CSS in JS, and still,
others simply install Material Design. There are many possibilities and depending on the
needs, everyone will surely find something for themselves. In this article, however, I would like
to focus on a solution that is completely different from those mentioned earlier. I’m talking
about a framework recently gaining publicity – Tailwind CSS.
The creators themselves refer to it as “utility first” because what you mainly get in it is a
set of existing classes that control individual aspects of the appearance and behaviour of
your application elements.
Do you remember mt-2 or invisible from Bootstrap? Then imagine Tailwind CSS only
consists of this.
https://tsh.io/blog/tailwind-css-tutorial/ 1/24
3/9/22, 12:42 Tailwind CSS tutorial & examples. Get started in 13 minutes
As I already mentioned, styling an application in Tailwind CSS is based on a set of classes which
are modifying one or two CSS attribute each. Each element will have a lot of such classes assigned
to it. This may seem crazy at first, but it works pretty well in practice.
Paradoxically, I’ve noticed that people who know CSS very well have the most difficulties with
migrating to Tailwind CSS. Such developers may get discouraged when they have to check what
class they should use to get the desired effect. After all, they could get the same result in a blink of
an eye by writing CSS attributes manually, which they know perfectly well.
From my own experience, however, I will say that it is worth making this mental shift, because
after learning a few rules governing the naming of classes in Tailwind CSS, your work will
significantly speed up, and styling the application may turn out to be faster than using traditional
CSS.
You have several classes used in this example. Leks check them one-by-one:
bg-green-300 – this class sets a green background (this the bg prefix). The value 300 in the
name is just the shade number.
border-green-600 – it’s similar to the previous class but it sets the elements borders colour
to a slightly darker green.
border-b – this class does nothing more than set the border to be visible only at the bottom
(“b” stands for “bottom”)
p-4 and m-4 those two classes make the margin and padding the size of 4 units. In
Tailwind CSS, this is equivalent to 16px.
rounded – finally, this sets the rounded corners for the element.
With all those classes the final effect will look like this:
If you don’t like the round corners, you can always adjust them. The rounded class has many
varieties, such as rounded-sm or rounder-lg , that give the element corners a smaller or larger
radius of rounding, respectively. It is also possible to round off only the selected corners.
https://tsh.io/blog/tailwind-css-tutorial/ 3/24
3/9/22, 12:42 Tailwind CSS tutorial & examples. Get started in 13 minutes
Also, as you can see, it is impossible to describe all CSS classes and their varieties here. Tailwind
CSS supports all popular CSS attributes and has many CSS classes to handle each of them.
Shadows, borders, grids, flexboxes, colours and fonts – all of this is well supported. If you are
interested, I encourage you to explore the Tailwind CSS documentation.
Special States
https://tsh.io/blog/tailwind-css-tutorial/ 4/24
3/9/22, 12:42 Tailwind CSS tutorial & examples. Get started in 13 minutes
What you saw above are the easiest ways to use Tailwind CSS classes. However, styling modern
applications is more than just static appearance. Views must be responsive and must change
according to the width of the device screen. Elements must also often react to mouse movement
and, for example, highlight when hovering over them with the cursor.
All such responsiveness and different states of various elements are often the weakest elements of
many low-level CSS frameworks. Not that the pure CSS was any better (writing media queries can
be a nightmare) but usually, even in frameworks, these syntaxes aren’t exactly elegant.
You don’t need a crystal ball to predict that. 🔮 Check out our “State of Frontend” report based on a
worldwide survey amongst 4500 developers.
However, Tailwind CSS is different. Here you operate on classes and if, for example, you want a
class to be active only when the user hovers the cursor over the button, it’s enough to precede such
class with the prefix of the CSS pseudoselector, e.g. hover:
https://tsh.io/blog/tailwind-css-tutorial/ 5/24
3/9/22, 12:42 Tailwind CSS tutorial & examples. Get started in 13 minutes
The above example shows how the hover prefix was used to change the background of an element.
Of course, Tailwind CSS supports other pseudo selectors as well. When it comes to more complex
cases from the day-to-day battlefield, Tailwind CSS also tries to help. For example, you can very
easily change the styles of the descendants of the selected element.
For this purpose, you just use the group class in the element that is to be hovered over and
the group-hover prefix in the descendant:
If you begin to worry about the increasing length of class attributes then please remain calm. We
will try to remedy this a bit later.
https://tsh.io/blog/tailwind-css-tutorial/ 6/24
3/9/22, 12:42 Tailwind CSS tutorial & examples. Get started in 13 minutes
In this example, you have created a block – the larger the screen on which you display it, the larger
its margin. Of course, nothing prevents you from adding more classes to an element at the same
time, preceded by the screen size prefix or some pseudoselector. Different prefixes can also be
concatenated to get classes like lg:hover:shadow-md .
Here you may ask yourself since Tailwind CSS supports most CSS attributes with dozens of classes
and each class can be preceded by one or more prefixes, will my application not grow by several
megabytes after adding this framework?
And that is a very good question. It turns out that Tailwind CSS doesn’t generate all possible
combinations by default. Moreover, it has the tools to remove unused classes and thus further
reduce the size of the resulting source code.
But to talk about it in detail, we need to explain how to install Tailwind CSS in your application and
how it works first.
How I ruined my JavaScript code and still won the Coding Challenge
https://tsh.io/blog/tailwind-css-tutorial/ 7/24
3/9/22, 12:42 Tailwind CSS tutorial & examples. Get started in 13 minutes
Tailwind CSS doesn’t work as a regular CSS library. This isn’t just a collection of styles that
you include in our CSS. You also need to properly transpile your code using Tailwind classes to get
working styles as a result.
While there are several ways to use Tailwind CSS, the recommended method is the PostCSS
preprocessor and a dedicated plugin that will generate the styles you need. The aforementioned
preprocessor works like other tools of this type, e.g. SCSS or LESS: it takes your code and with the
help of appropriate logic transpiles it into pure CSS. PostCSS has the advantage of being fully
extensible. You can write plugins for it and expand its capabilities depending on your needs. This is
a situation similar to Babel or Eslint.
If you use PostCSS, the exact way to install Tailwind CSS in your project will really depend on the
technology stack, you can easily find the right instruction for installing everything on the Internet. A
lot is also covered in the excellent Tailwind CSS documentation.
https://tsh.io/blog/tailwind-css-tutorial/ 8/24
3/9/22, 12:42 Tailwind CSS tutorial & examples. Get started in 13 minutes
For the purposes of this article, I will discuss how to install the CSS framework in question in
projects generated with the popular Create React App starter. Assuming that the project itself has
already been created, you can proceed to install the necessary libraries in the appropriate versions:
The problem with CRA is that this tool uses PostCSS internally and doesn’t allow to override its
preprocessor configuration in any built-in way. However, this isn’t a hopeless situation because you
can use CRACO, a tool for easily overwriting all CRA settings. So install CRACO in your project:
… and then we modify the commands in package.json so that your application launched with the
help of this tool:
{
//...
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test",
//...
}
}
The next step is to create a settings file for CRACO that will define how PostCSS configuration
should be overwritten. For this purpose, in the main folder of your application, create the
craco.config.js file and put the following content inside:
https://tsh.io/blog/tailwind-css-tutorial/ 9/24
3/9/22, 12:42 Tailwind CSS tutorial & examples. Get started in 13 minutes
module.exports = {
style: {
postcss: {
plugins: [
require('tailwindcss'),
require('autoprefixer'),
],
},
}
In the code above we added two plugins to the PostCSS configuration. The first is your Tailwind
CSS transpiler to generate all the classes you need, and the second is an autoprefixer that will ensure
all CSS attributes will be generated in versions for all browsers you should support.
Now that we have PostCSS configured, it’s time to add the Tailwind settings file itself. The fastest
way to do this is to generate it with the command:
After a while, the tailwind.config.js file will appear in the main folder of your project with the
following content:
module.exports = {
purge: [],
darkMode: false,
theme: {
extend: {},
},
variants: {
extend: {},
},
plugins: [],
}
https://tsh.io/blog/tailwind-css-tutorial/ 10/24
3/9/22, 12:42 Tailwind CSS tutorial & examples. Get started in 13 minutes
This configuration is empty for now, but you will have time to expand it a bit before the end of the
article. Now as long as you only add to the purge field the files in which you are going to use the
Tailwind classes. You can use the glob expressions:
module.exports = {
purge: [
'./src/**/*.{js,jsx,ts,tsx}',
'./public/index.html'
],
//...
}
This setting allows Tailwind CSS to check in the indicated files which classes you actually used in
your project and which of them should be added to the production build of our application. All
others will be cut out, reducing the final size of your styles.
For this mechanism to work properly, however, you must remember one rule: you
mustn’t dynamically concatenate class names anywhere in the code.
https://tsh.io/blog/tailwind-css-tutorial/ 11/24
3/9/22, 12:42 Tailwind CSS tutorial & examples. Get started in 13 minutes
Finally, there is one thing left to do. You need to indicate where you want to include this framework
in your application. And you can do it in two ways. Either by adding PostCSS understandable
instructions in one of your CSS files:
@tailwind base;
@tailwind components;
@tailwind utilities;
import "tailwindcss/tailwind.css";
The latter solution is preferable if your stack allows you to directly import CSS files to JS.
A tailor-made framework
https://tsh.io/blog/tailwind-css-tutorial/ 12/24
3/9/22, 12:42 Tailwind CSS tutorial & examples. Get started in 13 minutes
If you think Tailwind CSS may not be the best choice for you because you are afraid it will limit
you in some way, you can sleep well. Since all Tailwind classes are generated during the build, you
can easily modify them from the configuration file.
module.exports = {
theme: {
screens: {
'tablet': '640px',
'laptop': '1024px',
'desktop': '1280px',
},
},
//...
}
https://tsh.io/blog/tailwind-css-tutorial/ 13/24
3/9/22, 12:42 Tailwind CSS tutorial & examples. Get started in 13 minutes
With the above code, you have overwritten the default Tailwind breakpoints,
i.e. sm , md , lg , etc., and created your own. From now on, in your application, you can start
using such classes as tablet:font-weight or desktop:text-white , that are activated on the
resolutions indicated in the configuration file. If you need to use classes that are active up to a given
resolution or set some more advanced conditions, then everything is possible:
module.exports = {
theme: {
screens: {
'sm-max': {'max': '639px'},
'md-lg': {'min': '768px', 'max': '1023px'},
'md': [
{'min': '668px', 'max': '767px'},
{'min': '868px'}
]
'portrait': {'raw': '(orientation: portrait)'},
},
},
//...
}
For more examples and instructions on how to expand the breakpoint list without overwriting the
default ones, please visit the official documentation pages.
Another aspect of Tailwind CSS that many of you will want to customize is the availability of
colours. The easiest way to do this is by creating a palette from ready-made sets of shades. For
example, if you plan to use red and yellow and a few other primary colours, your palette could look
like this:
module.exports = {
theme: {
colors: {
red: colors.red,
yellow: colors.amber,
https://tsh.io/blog/tailwind-css-tutorial/ 14/24
3/9/22, 12:42 Tailwind CSS tutorial & examples. Get started in 13 minutes
black: colors.black,
white: colors.white,
gray: colors.coolGray,
transparent: 'transparent'
},
},
//...
};
Nothing prevents you from defining your own shades or naming the colours in a specific way:
module.exports = {
theme: {
colors: {
primary: {
light: '#ffcccb',
dark: '#8b0000',
},
secondary: {
light: '#b5651d',
dark: '#654321',
},
//...
},
},
//...
}
After such a reconfiguration of Tailwind CSS, you can refer to defined shades in the code using
classes such as bg-primary-light or text-secondary-dark .
Ok, what if you want to further modify the content of Tailwind’s built-in classes? This is also
possible and it is also done from the configuration file level. Let’s assume that according to your
class shadow-lg casts too soft shadows for your taste and you want to strengthen this effect a bit.
You can do it very easily by modifying the appropriate field in the theme settings:
https://tsh.io/blog/tailwind-css-tutorial/ 15/24
3/9/22, 12:42 Tailwind CSS tutorial & examples. Get started in 13 minutes
module.exports = {
theme: {
boxShadow: {
...defaultTheme.boxShadow,
lg: '0 10px 15px -3px rgba(0, 0, 0, 0.3), 0 4px 6px -2px rgba(0, 0, 0, 0.15)'
}
}
//...
}
Note how we have overridden the styles only for the lg variant, and left the rest of the settings
default, referring to the default theme. Of course, other classes can also be modified as shown.
One more thing! I’ve mentioned at the beginning of the article that by default Tailwind doesn’t
generate all prefix and class combinations. For example, without changing the settings, you cannot
use the active:shadow class in your application, which should appear on the button when it is
clicked (equivalent to button:active ). Tailwind simply doesn’t generate this class for the
default settings. How to change it? Pretty straightforward. That’s why there is a variants field in
the configuration, to set additional prefix combinations that we need.
module.exports = {
variants: {
extend: {
shadow: ['active'],
//...
},
},
//...
};
So far, you have only modified existing class sets. Tailwind, despite being a very universal tool,
doesn’t have classes for absolutely all CSS attributes or cases of their use. Tailwind also doesn’t
support e.g. CSS attributes which are not yet supported in all browsers. Can Tailwind help you to
create your own classes? As it turns out – yes.
You can order Tailwind to generate single classes or whole sets of classes with different prefixes.
This is done in a CSS file using the @layers at-rule For example, Tailwind doesn’t support CSS
filters, so if you want to display elements in shades of grey on your website, you can add the
missing filter support in the following way:
@layer utilities {
.filter-grayscale {
filter: grayscale(100%);
}
.filter-none {
filter: none;
https://tsh.io/blog/tailwind-css-tutorial/ 17/24
3/9/22, 12:42 Tailwind CSS tutorial & examples. Get started in 13 minutes
}
}
Thanks to this, you can now combine your filter-grayscale and filter-none classes with
the hover and focus prefixes and thus, for example, make colourful pictures only when they are
indicated by the cursor.
<img
src="https://bit.ly/2MrYzwH"
className="filter-grayscale hover:filter-none ..."
alt=”Kitty in grass”
/>
Generating classes works great. But in this form, it can be quite a chore to define if you want to do a
whole range of classes (e.g. set a different filter power in the range from 0 to 100 in increments of
10). Do you have to write everything manually then? Fortunately, Tailwind comes to your aid here
as well.
https://tsh.io/blog/tailwind-css-tutorial/ 18/24
3/9/22, 12:42 Tailwind CSS tutorial & examples. Get started in 13 minutes
You can write your own utility plugin for this framework that will generate
definitions for a whole range of styles.
To add such a plug, you have to go back to your configuration file and import a file in
the plugins field, where you will store your styles generator.
module.exports = {
//...
plugins: [
require('./filter.tailwind'),
]
}
The second step is to write the generator itself that produces all the class descriptions you need. In
my scenario, the content of filter.tailwind.js looks like this:
addUtilities(newUtilities, {
variants: ['responsive', 'hover'],
})
});
https://tsh.io/blog/tailwind-css-tutorial/ 19/24
3/9/22, 12:42 Tailwind CSS tutorial & examples. Get started in 13 minutes
When you look at it, there is nothing complicated here. First, you add a class that turns off grayscale
to the object, i.e. .filter-none . Later in the loop, you add more classes from .filter-
grayscale-10 all the way to .filter-grayscale-100 . Finally, the prepared data is sent to
the addUtilities function, indicating in the second parameter that the created classes are to
support hover prefixes and those related to responsiveness.
And that’s it. All 10 classes with variants with different prefixes are ready for use. As you can see,
writing Tailwind plugins is super easy. However, before you start doing it, I suggest that you always
check if there is any ready-made solution on the Internet. There are many open-source plugins that
are just waiting to be used, such as webdna/tailwindcss-aspect-ratio, which I highly recommend.
Looking for a Frontend job? We've got some great tips here
Trimming classes
https://tsh.io/blog/tailwind-css-tutorial/ 20/24
3/9/22, 12:42 Tailwind CSS tutorial & examples. Get started in 13 minutes
There is one more thing that I promised to mention. How to deal with long, expanding class lists? In
the end, sooner or later this will happen to you:
I used 11 classes to describe this button, and in fact, not much is going on here. And I didn’t even
take care of the button responsiveness yet! It’s hard to think about what could happen with much
more complicated web components.
https://tsh.io/blog/tailwind-css-tutorial/ 21/24
3/9/22, 12:42 Tailwind CSS tutorial & examples. Get started in 13 minutes
Fortunately, Tailwind CSS has solutions for this. First, you can define in your CSS file a so-called
Tailwind component that will collect several atomic classes and combine them into one more
complex class. There are two at-rules used here: @layer and @apply :
@layer components {
.button-blue-rounded {
@apply text-white font-semibold bg-blue-500 ...;
}
}
If you don’t like creating components from ready-made classes, you can go back to writing plugins.
Component plugins are just as easy to write as utility plugins, and they allow us to define new
complex styles using CSS in JS.
const newComponents = {
'.button-blue': {
...base,
background: theme('colors.blue.500'),
},
'.button-red': {
...base,
background: theme('colors.red.600'),
}
};
addComponents(newComponents, {
variants: ['responsive', 'hover'],
})
});
https://tsh.io/blog/tailwind-css-tutorial/ 22/24
3/9/22, 12:42 Tailwind CSS tutorial & examples. Get started in 13 minutes
Creating components has another advantage over using atomic classes directly in your HTML code.
When debugging you can better see what part of the code you are looking at because there are more
telling names. Therefore, as I practice the method, I always create components to make the
application code more readable and easier to develop. Please compare those two buttons yourself:
Sample code
Even if you think that this framework is not suitable for creating large dedicated
applications, it is worth knowing it for building quick prototypes, responsive design,
interactive elements, large screens design, navigation bars etc. Once we learn its class
nomenclature, including utility classes, Tailwind CSS will immediately speed up creating
each project and allow you to focus on business values instead of the details of CSS
styling. Among other CSS frameworks, Tailwind CSS really stands out with its ability to
deliver business value quickly.
Nevertheless, I believe Tailwind CSS also has its place in big projects. Developers
don’t need to come up with names for many classes and aren’t obliged to check if
someone else created any utils anymore. When you use Tailwind, you get all the
tools right away, including utility first classes, custom designs etc. Writing code
with Tailwind CSS is really straightforward!
https://tsh.io/blog/tailwind-css-tutorial/ 23/24
3/9/22, 12:42 Tailwind CSS tutorial & examples. Get started in 13 minutes
In addition, Tailwind also helps you use a defined colour palette and maintain consistent
spacing in the layout. And as we know: the bigger the project, the more people in the team,
the harder it is to keep such things in check. Therefore, I propose to give this framework a
chance. It will help to maintain the high quality of the code, which is a value for both
developers and business.
https://tsh.io/blog/tailwind-css-tutorial/ 24/24