TaskBuild the SAME button two ways. .btn-utility uses the long Tailwind-style class string in HTML (style with: padding 8px 16px, bg #3B82F6, color white, rounded-md, shadow). .btn-component is just <button class='btn-primary'> with all the styles defined in CSS.
Utility-first (Tailwind primer revisited)
75 XP6 min
Theory
Recap from B1 lesson 16 β now critique it
Utility-first CSS = a class per declaration:
<button class="bg-blue-500 text-white px-4 py-2 rounded-lg shadow hover:bg-blue-600"> Click me </button>
vs component-style:
<button class="btn btn-primary">Click me</button> <!-- where .btn-primary CSS is elsewhere -->
Why utility-first wins (Tailwind's argument)
- No naming. You don't invent
.btn-primary-large-disabledβ you composebg-blue-500 px-6 py-3 opacity-50. - No file switching. All styling in the template you're looking at.
- No unused CSS. Tailwind purges unused classes at build.
- Constraint-driven. Tailwind's classes follow a 4/8/12/16/20 spacing scale β you can't accidentally pick "13px" for padding.
Why utility-first loses (the criticism)
- HTML gets noisy β 20-character class strings.
- Duplication on repeat β same string of classes copied 50 times.
- Hard to refactor β "make all primary buttons blue" requires search-and-replace across templates.
The synthesis (2026 reality)
Most teams use BOTH:
- Utility classes for one-off layouts and prototyping.
- Component classes (
.btn-primary) for reused widgets, often built FROM Tailwind utilities via @apply.
.btn-primary {
@apply bg-blue-500 text-white px-4 py-2 rounded-lg shadow;
}
.btn-primary:hover {
@apply bg-blue-600;
}Best of both: short HTML, single source of truth.
π
Sign up to start coding
Theory is open to everyone. The interactive editor, live preview, and check are unlocked with a 7-day free trial β card required, cancel anytime.
Sign up β free trial βFirst 10 lessons in each track are free. No card needed for those.