Converting CSS to Tailwind
Migrate plain CSS files to Tailwind utility classes applied directly in markup.
Workflow
- Read the CSS file and inventory every rule
- Find the corresponding markup (HTML, JSX, TSX, Vue, Svelte) that references each selector
- Convert each rule using the mapping below
- Delete the CSS rule once all its properties are expressed as utilities
- Remove the CSS file (or import) once it's empty
- Verify the page looks identical — check for visual regressions
Conversion Reference
Layout & Box Model
| CSS | Tailwind |
|---|---|
display: flex |
flex |
display: grid |
grid |
display: none |
hidden |
position: relative |
relative |
position: absolute |
absolute |
justify-content: center |
justify-center |
align-items: center |
items-center |
gap: 16px |
gap-4 |
width: 100% |
w-full |
max-width: 768px |
max-w-3xl |
margin: 0 auto |
mx-auto |
padding: 16px |
p-4 |
overflow: hidden |
overflow-hidden |
Typography
| CSS | Tailwind |
|---|---|
font-size: 14px |
text-sm |
font-weight: 700 |
font-bold |
line-height: 1.5 |
leading-normal |
text-align: center |
text-center |
text-transform: uppercase |
uppercase |
color: #333 |
text-[#333] or a theme color |
letter-spacing: 0.05em |
tracking-wide |
Backgrounds & Borders
| CSS | Tailwind |
|---|---|
background-color: #f5f5f5 |
bg-[#f5f5f5] or bg-neutral-100 |
border: 1px solid #e5e7eb |
border border-gray-200 |
border-radius: 8px |
rounded-lg |
box-shadow: 0 1px 3px ... |
shadow-sm |
Responsive — Media Queries
@media (min-width: 768px) { .card { flex-direction: row; } }
→ <div class="flex-col md:flex-row">
Map breakpoints: sm: (640), md: (768), lg: (1024), xl: (1280), 2xl: (1536)
Pseudo-classes & States
.btn:hover { background-color: #1d4ed8; }
→ <button class="hover:bg-blue-700">
Prefixes: hover:, focus:, active:, disabled:, first:, last:, odd:, even:, group-hover:, peer-checked:
Animations & Transitions
transition: all 0.2s ease-in-out;
→ transition-all duration-200 ease-in-out
@keyframes spin { ... }
animation: spin 1s linear infinite;
→ animate-spin (built-in) or define in tailwind.config
Custom Properties / Arbitrary Values
For anything without a direct utility, use arbitrary values:
w-[calc(100%-2rem)]grid-cols-[200px_1fr_1fr]text-[clamp(1rem,2vw,1.5rem)]
Handling Remaining CSS
Some things can't be expressed purely as utilities:
- Complex selectors (
.parent > .child + .sibling) — restructure the markup or use@applyas a last resort @font-face— keep in a global CSS file orglobals.css- Complex
@keyframes— define intailwind.config.tsundertheme.extend.keyframes - CSS variables — migrate to Tailwind theme values in
tailwind.config.ts
Rules
- Prefer semantic Tailwind classes (
bg-primary) over arbitrary hex values when a theme exists - Don't use
@applyto recreate the same CSS you're migrating away from — that defeats the purpose - Group related utilities logically: layout → spacing → typography → colors → effects
- If a component has 10+ utilities, consider extracting a reusable component rather than a CSS class