Let's compare how you'd build the same card component using traditional CSS versus Tailwind CSS. This side-by-side comparison makes the differences crystal clear.
The traditional CSS way
First, you write your HTML with semantic class names. Then you jump to your CSS file and style each class. You need to name things, manage specificity, and maintain two files in sync.
<div class="card">
<img class="card-image" src="photo.jpg" alt="Photo">
<div class="card-body">
<h3 class="card-title">My Card</h3>
<p class="card-text">Some description here.</p>
<a class="card-button" href="#">Learn More</a>
</div>
</div>
.card {
border-radius: 0.5rem;
overflow: hidden;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.card-image {
width: 100%;
height: 200px;
object-fit: cover;
}
.card-body {
padding: 1.5rem;
}
.card-title {
font-size: 1.25rem;
font-weight: 700;
margin-bottom: 0.5rem;
}
.card-button {
display: inline-block;
margin-top: 1rem;
padding: 0.5rem 1rem;
background-color: #3b82f6;
color: white;
border-radius: 0.25rem;
}
The Tailwind way
No separate CSS file. No class naming. Just utilities applied directly to your HTML elements.
<div class="rounded-lg overflow-hidden shadow-md">
<img class="w-full h-48 object-cover" src="photo.jpg" alt="Photo">
<div class="p-6">
<h3 class="text-xl font-bold mb-2">My Card</h3>
<p class="text-gray-600">Some description here.</p>
<a class="inline-block mt-4 px-4 py-2 bg-blue-500 text-white rounded
hover:bg-blue-600" href="#">Learn More</a>
</div>
</div>
The key differences
- No file switching. Everything lives in your HTML. No context switching between files.
- No naming debates. You don't need to come up with
.card-bodyor.card-wrapper. Just applyp-6. - No dead CSS. When you delete an element, the classes go with it. No orphaned CSS rules sitting around.
- Consistent design. Tailwind's default theme ensures your spacing, colors, and sizes follow a cohesive scale.