July 2026
Why I Replaced Tailwind with Plain CSS for Croatian Blog Layouts
Discover why plain CSS outperforms Tailwind for Croatian blog layouts—cleaner markup, smaller bundles, and easier client edits
I still remember the exact moment I deleted Tailwind from a client project last spring. We were building a travel blog for an Istrian wine route, and the HTML looked like a shopping list of utility classes: flex items-center justify-between p-4 md:p-6 lg:flex-row. The markup was unreadable, the bundle was bloated, and my Croatian client—who needed to edit content in WordPress—couldn't make sense of a single line. So I stripped it all out, wrote 200 lines of plain CSS, and never looked back.
The Real Problem with Utility-First in Local Content Projects
Tailwind works beautifully for app dashboards and component libraries. But Croatian blog layouts come with a different set of constraints that the utility-first gospel ignores.
Language-Specific Typography Breaks the System
Croatian text has diacritics—č, ć, š, đ, ž—that behave unpredictably with Tailwind's default font stacks. I once spent two hours debugging why font-sans rendered č as a broken box on Safari iOS. The issue wasn't the font itself; it was Tailwind's aggressive normalization layer conflicting with the system fonts I'd chosen for readability.
With plain CSS, I write:
body {
font-family: 'Source Serif 4', 'Georgia', serif;
-webkit-font-smoothing: antialiased;
font-optical-sizing: auto;
}
That's it. No purge issues, no missing variants, no @apply hacks to override utility classes that shouldn't exist in the first place.
The Line-Height Trap for Long-Form Content
Blog layouts are typography-first. Tailwind's default line-height of leading-relaxed (1.625) is decent, but Croatian text—with its longer average word length compared to English—needs more granular control. I found myself writing leading-[1.8] on almost every paragraph tag, which defeats the purpose of a utility framework.
Plain CSS gives me:
article p {
line-height: 1.75;
max-width: 68ch;
margin-bottom: 1.5rem;
}
One rule. Every paragraph. No mental overhead.
Why Croatian Blog Editors Hate Tailwind
This is the part that people in the global Tailwind echo chamber ignore. Most Croatian blogs run on WordPress, Shopify, or custom CMS platforms where non-developers edit content.
The Class List Nightmare
When a client opens the HTML editor in WordPress and sees class="mt-4 mb-6 text-lg font-medium leading-relaxed text-gray-800 prose prose-h2:text-2xl", they freeze. They don't know which class controls the spacing, which controls the color, or what happens if they remove one.
With plain CSS and semantic class names, the same element looks like:
<p class="blog-body-text">Ovo je primjer hrvatskog teksta s č, ć i š.</p>
The client can add any element, apply blog-body-text, and it works. No framework knowledge required.
The Customization Wall
Croatian blogs often need unique touches: a gradient overlay on hero images that matches the Dalmatian sunset colors, a pull-quote style that uses local typographic traditions, or a responsive table for comparing local wine prices. Tailwind makes these customizations painful because you're fighting against the design system's constraints.
For a recent blog about Plitvice Lakes hiking trails, I needed a specific caption style that combined a small-caps font with a dashed underline. In Tailwind, I would have written:
<figcaption class="text-xs uppercase tracking-widest text-gray-500 border-b border-dashed border-gray-300 pb-1">
In plain CSS:
figcaption.caption-plitvice {
font-size: 0.75rem;
font-variant: small-caps;
letter-spacing: 0.15em;
color: #6b7280;
border-bottom: 1px dashed #d1d5db;
padding-bottom: 0.25rem;
}
Both work. But the CSS version is reusable, inspectable in DevTools without parsing 12 utility classes, and doesn't break when I upgrade Tailwind versions.
Performance Gains You Can Measure
I'm not anti-Tailwind for performance—PurgeCSS does a decent job. But the numbers for a typical Croatian blog tell a different story.
The Bundle Size Reality
A standard Tailwind setup with a few custom colors and breakpoints produces a CSS file around 15–25 KB gzipped. That's fine. But the HTML payload balloons because every element carries 5–15 utility classes. For a blog with 50 articles, that's megabytes of extra markup transferred over mobile connections—and Croatian mobile internet, while improving, still has rural dead zones where every kilobyte matters.
Plain CSS for the same blog: 4–8 KB gzipped total. The HTML is clean. The total page weight drops by 30–40%.
Render Performance Without the Overhead
Tailwind generates thousands of utility classes, many of which you never use. Even with PurgeCSS, the framework's cascade layer adds specificity weight that plain CSS avoids. I've measured a 12% faster First Contentful Paint on a Croatian news blog after removing Tailwind, simply because the browser had fewer CSS rules to evaluate before rendering text.
A Concrete Example: The Istrian Wine Route Redesign
Let me walk you through the exact project I mentioned in the intro. It's a small blog covering wineries along the Istrian wine route—Momjan, Buje, Grožnjan. The client, a local sommelier, wanted a clean, readable layout with large hero images and responsive tables for wine tasting notes.
The Tailwind Version
I started with Tailwind because that's what I knew. The homepage hero section looked like this:
<section class="relative h-[60vh] min-h-[400px] flex items-center justify-center bg-gradient-to-b from-stone-900/80 to-stone-900/40">
<div class="relative z-10 text-center px-4 max-w-3xl mx-auto">
<h1 class="text-4xl md:text-5xl lg:text-6xl font-bold text-white mb-4 leading-tight">Istarska vinska ruta</h1>
<p class="text-lg md:text-xl text-stone-200 max-w-2xl mx-auto leading-relaxed">Otkrijte najbolje vinarije Istre kroz naše preporuke</p>
</div>
<div class="absolute inset-0 bg-cover bg-center" style="background-image: url('hero.jpg')"></div>
</section>
It worked. But the HTML was 12 lines for what should be a semantic 6-line section. Every time the client wanted to change the overlay opacity, I had to rebuild the gradient value and re-deploy.
The Plain CSS Version
After the rewrite:
<section class="hero-wine">
<div class="hero-wine__overlay"></div>
<div class="hero-wine__content">
<h1>Istarska vinska ruta</h1>
<p>Otkrijte najbolje vinarije Istre kroz naše preporuke</p>
</div>
</section>
.hero-wine {
position: relative;
height: 60vh;
min-height: 400px;
display: flex;
align-items: center;
justify-content: center;
background: url('hero.jpg') center/cover no-repeat;
}
.hero-wine__overlay {
position: absolute;
inset: 0;
background: linear-gradient(to bottom, rgba(28,25,23,0.8), rgba(28,25,23,0.4));
}
.hero-wine__content {
position: relative;
z-index: 10;
text-align: center;
padding: 0 1rem;
max-width: 48rem;
margin: 0 auto;
}
.hero-wine__content h1 {
font-size: 2.25rem;
font-weight: 700;
color: white;
margin-bottom: 1rem;
line-height: 1.25;
}
@media (min-width: 768px) {
.hero-wine__content h1 {
font-size: 3rem;
}
}
@media (min-width: 1024px) {
.hero-wine__content h1 {
font-size: 3.75rem;
}
}
.hero-wine__content p {
font-size: 1.125rem;
color: #e7e5e4;
max-width: 42rem;
margin: 0 auto;
line-height: 1.625;
}
@media (min-width: 768px) {
.hero-wine__content p {
font-size: 1.25rem;
}
}
More lines of CSS, yes. But the HTML is semantic, the client can edit the text without touching styles, and I can change the overlay from 80% to 60% opacity in one place—not across 15 utility classes.
The Maintenance Reality After Six Months
I've now maintained both approaches across five Croatian blogs. Here's what I've learned.
When Tailwind Still Makes Sense
If you're building a React-based web app with a dedicated design system and a team of developers who all know the framework, Tailwind is fine. I use it for internal tools and SaaS dashboards. But for content-driven sites targeting Croatian readers, the trade-offs aren't worth it.
The Hidden Cost of Framework Lock-In
Every Tailwind upgrade introduces breaking changes. Version 3 added arbitrary values, which helped, but version 4 is rewriting the entire configuration layer. If you have a blog that runs for three years—common for Croatian tourism sites—you'll either freeze your dependencies or spend days migrating.
Plain CSS written in 2022 still works perfectly in 2025. No migration. No breaking changes. No purge config to debug.
The Accessibility Win
Croatian users with screen readers benefit from semantic HTML. Tailwind doesn't prevent semantic markup, but it encourages developers to think in terms of visual classes rather than content structure. When I write plain CSS, I naturally think about heading hierarchy, focus states, and color contrast because I'm writing rules for elements, not visual properties.
For the wine route blog, I added a skip navigation link and proper heading levels in under 30 minutes. The client's accessibility score went from 72 to 96 on Lighthouse.
Practical Takeaway: Write Your Own CSS, Own Your Layout
If you're building a blog for a Croatian audience—whether it's about travel, food, business, or culture—start with plain CSS and add framework utilities only when you genuinely need them. Your clients will thank you when they can edit content without breaking the layout. Your users will thank you when pages load faster on mobile data. And you'll thank yourself when you revisit the code six months later and understand exactly what every line does.
The next time you reach for Tailwind, ask yourself: does this blog need a design system, or does it need good typography and readable code? For most Croatian blogs, the answer is the latter.