Tailwind CSS Introduction

Tailwind CSS · Lesson 1 of 27 7 min read Updated

Tailwind CSS is a CSS framework that lets you style a page by adding small, single-purpose classes to your HTML. Instead of inventing a class name such as .product-card and then writing CSS for it in another file, you write class="rounded-xl bg-white p-6 shadow-md" directly on the element. Each of those classes does exactly one job.

In this lesson you will see how this utility-first approach compares with traditional CSS, why so many teams use it, what people worry about at first, and you will run your first Tailwind page. You should already know basic HTML and CSS; if not, start with the CSS tutorial.

What is a utility class?

A utility class is a class that applies one small piece of styling. Tailwind ships thousands of them, named after what they do:

ClassCSS it adds
p-6padding: 1.5rem
bg-whitebackground-color: white
rounded-xlborder-radius: 0.75rem
text-xlfont-size: 1.25rem with a matching line height
font-semiboldfont-weight: 600
shadow-mda medium box shadow

You combine many of these on one element to build a design. "Utility-first" means utilities are your first tool; you only write your own CSS when a utility does not exist for the job.

Traditional CSS vs utility-first

Here is a small product card for Meera's handloom shop in Jaipur, written the traditional way. You invent class names in the HTML, then style them in a stylesheet.

HTML
<div class="product-card">
  <h2 class="product-title">Cotton Kurta</h2>
  <p class="product-price">₹1,299</p>
  <button class="buy-button">Add to cart</button>
</div>
CSS
.product-card { max-width: 20rem; padding: 1.5rem; border-radius: 0.75rem;
                background: white; box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1); }
.product-title { font-size: 1.25rem; font-weight: 600; color: #0f172a; }
.product-price { margin-top: 0.25rem; color: #0369a1; }
.buy-button { margin-top: 1rem; padding: 0.5rem 1rem; border-radius: 0.5rem;
              background: #0284c7; color: white; }
.buy-button:hover { background: #0369a1; }

Now the same card with Tailwind. There is no separate stylesheet; the styling lives in the class attributes. Run it and hover over the button.

HTMLTry it yourself
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>First Tailwind card</title>
  <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.3.3"></script>
</head>
<body class="bg-slate-100 p-8">
  <div class="max-w-xs rounded-xl bg-white p-6 shadow-md">
    <h2 class="text-xl font-semibold text-slate-900">Cotton Kurta</h2>
    <p class="mt-1 text-sky-700">₹1,299</p>
    <button class="mt-4 rounded-lg bg-sky-600 px-4 py-2 text-white hover:bg-sky-700">
      Add to cart
    </button>
  </div>
</body>
</html>

Read the button's classes from left to right: top margin mt-4, rounded corners rounded-lg, a sky-blue background bg-sky-600, horizontal padding px-4, vertical padding py-2, white text text-white, and a darker background on hover hover:bg-sky-700. Once you know the naming pattern, you can read a design straight from the HTML.

Why developers like it

  • No naming. You do not stop every few minutes to invent names like .card-wrapper-inner. Naming things is surprisingly tiring.
  • You change things in one place. To make the price bold, you add font-bold to that element. You do not hunt through a large stylesheet, worried that changing .product-price will break another page.
  • CSS stops growing. In a traditional project, the stylesheet grows with every new feature. With Tailwind, the same few hundred utilities are reused everywhere, and the build only includes classes you actually used.
  • A built-in design system. Spacing, colours, font sizes and shadows come from a fixed scale (p-4, p-6, p-8), so designs stay consistent instead of mixing 13px, 15px and 17px.
  • States and screen sizes inline. Prefixes such as hover: and md: let you write hover styles and responsive layouts right on the element.

"Isn't this just inline styles?"

It looks similar, but utility classes can do things the style attribute cannot:

HTML
<!-- Inline styles: no hover, no media queries, any random value -->
<a style="color: #0369a1; padding: 13px">Results</a>

<!-- Tailwind: hover state, screen-size rules, values from a scale -->
<a class="p-3 text-sky-700 hover:underline md:p-4">Results</a>

A style attribute cannot target :hover or a media query, and it accepts any value, so designs drift. Tailwind classes are real CSS rules, so they support states, breakpoints, dark mode and everything else CSS can do.

The other common worry is long class lists. In real projects you do not copy the same twenty classes everywhere: you put the markup in a reusable component or a loop, so the class list is written once. You will learn this in Reusable Components.

Responsive and interactive, without leaving the HTML

This example shows two prefixes you will use constantly. md: applies a class only on screens 768px and wider, and hover: applies it only when the pointer is over the element. Make the result window narrower and wider to see the layout change.

HTMLTry it yourself
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Responsive notice</title>
  <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.3.3"></script>
</head>
<body class="p-6">
  <div class="flex flex-col gap-3 rounded-lg bg-amber-100 p-4 md:flex-row md:items-center md:justify-between">
    <p class="text-amber-900">Exam forms for BCA semester 3 close on 15 November.</p>
    <a href="#" class="rounded-md bg-amber-600 px-4 py-2 text-center text-white hover:bg-amber-700">
      Fill the form
    </a>
  </div>
</body>
</html>

On a phone, the text and button stack in a column (flex-col). From 768px up, md:flex-row puts them side by side and md:justify-between pushes them apart.

Tailwind vs component frameworks

Bootstrap and similar frameworks give you ready-made components: add class="btn btn-primary" and you get a finished button that looks like every other Bootstrap button. Tailwind gives you no finished components. It gives you building blocks, and you design the button yourself. That takes a little more effort at the start, but your site does not look like everyone else's, and you never fight the framework to undo its styles.

Tailwind CSS version 4 was released in January 2025 with a new, faster engine and a new way to configure it in CSS instead of JavaScript. This course teaches Tailwind CSS 4.3. You will still meet version 3 projects with a tailwind.config.js file; the lesson Upgrading from v3 to v4 shows both.

Common mistakes

  • Expecting default browser styles. Tailwind resets headings, lists and margins, so an <h1> looks like normal text until you add classes such as text-3xl font-bold. This is deliberate; see How Utility Classes Become CSS.
  • Using the browser build in production. The script tag is for learning and prototypes only.
  • Fighting the scale. Beginners reach for exact pixel values everywhere. Try the nearest scale value first (p-3 or p-4); consistent spacing looks better.

Key points

  • Tailwind is a utility-first CSS framework: you style elements with small, single-purpose classes.
  • Utility classes are real CSS rules, so unlike inline styles they support hover:, breakpoints such as md: and more.
  • Values come from a shared scale, which keeps spacing, colour and type consistent.
  • Tailwind has no ready-made components; you build your own design from utilities.
  • This course teaches Tailwind CSS 4.3. The browser build in our examples is for learning; real projects use a build step.

Exercise

Open the first example in the Try-it editor and change the card into a ticket for a cricket match in Kochi. Make the heading India vs Australia, the price ₹2,500, and the button Book seat. Change the button colour from sky to green (use bg-green-600 and hover:bg-green-700), and make the price bold with font-bold.

Show solution
HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Match ticket</title>
  <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.3.3"></script>
</head>
<body class="bg-slate-100 p-8">
  <div class="max-w-xs rounded-xl bg-white p-6 shadow-md">
    <h2 class="text-xl font-semibold text-slate-900">India vs Australia</h2>
    <p class="mt-1 font-bold text-green-700">₹2,500</p>
    <button class="mt-4 rounded-lg bg-green-600 px-4 py-2 text-white hover:bg-green-700">
      Book seat
    </button>
  </div>
</body>
</html>

Only class names changed: bg-green-600 and hover:bg-green-700 recolour the button, and font-bold makes the price bold. No stylesheet was touched.

Quick Quiz

1. What does "utility-first" mean in Tailwind CSS?

2. Which thing can a Tailwind class do that an inline style attribute cannot?

3. What does the class px-4 do?

4. Why do the examples in this course use a <script> tag to load Tailwind?

Learn Tailwind CSS with a mentor

Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call