Guide
Turning a stylesheet into Tailwind utility classes
Moving a project to Tailwind CSS means translating every rule in the old stylesheets into utility classes, and looking up the class for each declaration is slow even when you know CSS well. This converter reads a stylesheet and writes the Tailwind classes for each selector, using the default theme where values match and arbitrary values where they do not, so the result looks the same as before.
Declarations to utilities
Each declaration is translated on its own. Keywords map directly: display: flex becomes flex, flex-direction: column becomes flex-col, justify-content: space-between becomes justify-between, and display: none becomes hidden. Lengths are matched against the spacing scale, where each step is 0.25rem, so 8px and 0.5rem both become 2 and 16px becomes 4. Font sizes, weights, line heights, letter spacing and border radii are matched against their own scales: 1.125rem is text-lg, 600 is font-semibold and 8px radius is rounded-lg.
Shorthands
Padding and margin shorthands are expanded the way CSS reads them. padding: 8px 16px becomes py-2 px-4, margin: 0 auto becomes my-0 mx-auto, and four different values become four side utilities. A border shorthand becomes width, style and colour utilities, so border: 1px solid #e5e7eb gives border border-[#e5e7eb], since solid is Tailwind’s default style.
Arbitrary values
When a value is not on the default scale, guessing the nearest class would quietly change the design, so the converter writes an arbitrary value instead: font-size: 13px becomes text-[13px] and a custom colour becomes bg-[#2563eb]. Spaces inside arbitrary values are written as underscores, which Tailwind turns back into spaces. Replace them with theme names later if you add those colours and sizes to your theme.
Variants
State selectors become variants on the same element’s classes. A .card:hover rule adds hover: classes to .card, and ::before and ::after become before: and after:, with an empty content written as content-['']. Media queries with min-width at Tailwind’s breakpoints, 640, 768, 1024, 1280 and 1536 pixels, become sm: to 2xl:, and prefers-color-scheme: dark becomes dark:. Other media queries become arbitrary variants.
A worked example
The Sample stylesheet styles a card. .card becomes class="flex flex-col gap-3 py-4 px-6 bg-white border border-[#e5e7eb] rounded-lg shadow-[0_1px_3px_rgba(0,_0,_0,_0.1)] hover:border-[#2563eb] md:flex-row md:p-6", combining the base rule, the hover rule and the 768px media query. .card-title becomes class="text-lg font-semibold leading-tight text-[#111827] m-0". The animation declaration on .card-body is listed under “not converted”, since an animation needs keyframes defined in the theme.
What is left as CSS
Animations, grid template areas, complex selectors that target other elements (such as .list > li + li) and properties without utilities are listed per selector so nothing disappears silently. Keep those in a small stylesheet or use @apply and arbitrary properties such as [mask-type:luminance].
Finishing a migration
Paste the classes into the markup, remove the old rules, and compare the page in the browser. Then replace repeated arbitrary values with theme tokens, and extract repeated class lists into components rather than @apply, as the Tailwind documentation recommends.
Related tools
- HTML to JSX converts the markup the classes go on.
- CSS Specificity Calculator explains the old cascade you are replacing.
- Code Minifier compresses the CSS you keep.
- Color Converter turns hex values into other colour formats.
Checked against the current version of the CSS to Tailwind on .

