How to Convert Tailwind HTML to Structured, Semantic CSS (Without a Full Rewrite)
I've been using Tailwind for about two years across a handful of projects. It's fast, it's predictable, and once the muscle memory kicks in you can style things without switching files.
But here's what I kept running into:
That component you built six months ago? The one with flex items-center justify-between p-4 bg-white rounded-lg shadow-md on the outer div, plus another half-dozen classes on each child element? When you come back to refactor it, you're reading styling before you're reading structure. And if you want to move that component into a project that doesn't use Tailwind — or hand it off to someone who doesn't know the utility vocabulary — you're stuck.
The tooling gap
I went looking for something that could take a chunk of Tailwind-styled HTML and give me back clean, semantic CSS. Not one-to-one class translation (there are a dozen tools that do px-4 → padding: 1rem). I wanted something that understood the component structure — that a button inside a card should become .card-button, not .element-4.
What I found:
One-to-one converters — great if you just need to know what gap-4 compiles to, but they output .element {} .div {} flat rules with no hierarchy
StyleLens (VSCode) — finds duplicate utility patterns and suggests refactoring into @apply, but it's an editor workflow, not an export tool
Tailwind's own @apply — moves the problem from the HTML to the CSS file but doesn't change the naming problem
None of them did what I actually wanted: paste some HTML, get back component-level CSS with meaningful class names.
What I ended up building
Since I couldn't find it, I put together a minimal tool that does exactly that. The idea is simple:
- Parse the HTML tree
- Translate every Tailwind class to its CSS equivalent
- Group declarations by component (the tree structure tells you what belongs where)
- Name things based on what they are — semantic tags like h2 become .card-title, buttons become .card-button, etc.
Here's what it looks like in practice.
Input:
< img class="w-full h-48 object-cover" src="img.jpg" />
Card Title
Description goes here.
Get Started Output: .card { max-width: 24rem; margin-left: auto; margin-right: auto; background-color: #ffffff; border-radius: 0.75rem; box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1); overflow: hidden; }
.card-image {
width: 100%;
height: 12rem;
object-fit: cover;
}
.card-body {
padding: 1.5rem;
}
.card-title {
font-size: 1.25rem;
font-weight: 700;
color: #111827;
}
.card-description {
margin-top: 0.5rem;
color: #4b5563;
}
.card-button {
margin-top: 1rem;
padding-left: 1rem;
padding-right: 1rem;
padding-top: 0.5rem;
padding-bottom: 0.5rem;
background-color: #2563eb;
color: #ffffff;
border-radius: 0.25rem;
}
.card-button:hover {
background-color: #1d4ed8;
}

Top comments (0)