A Tailwind class converter is the fastest way to answer two questions that come up constantly on any project that uses utility classes: what CSS does this string of classes actually produce, and what would this existing CSS look like as utilities? Both come up during migrations, in code review, and every time somebody inherits a component and needs to know what py-3 really means in pixels before changing it. This page does both conversions in your browser, against the default Tailwind v3 theme, and is deliberately explicit about the cases where a clean conversion is impossible.
Arb Digital's front-end team built this while migrating client sites between hand-written stylesheets and utility-first markup, where the expensive mistakes are always the silent ones. A converter that quietly guesses at an unknown class produces markup that looks right and renders wrong. This one refuses to guess: every token it cannot map with certainty appears in the output as a labelled comment, and the fourth counter above tells you how many there are before you copy anything.
What This Tailwind Class Converter Does
In the forward direction, paste a class attribute and the tool expands each utility into the declarations it compiles to. px-6 becomes padding-left: 1.5rem; padding-right: 1.5rem. text-sm becomes a font size and its paired line height, because Tailwind's type scale sets both. rounded-lg, shadow-md, bg-blue-600 and the rest resolve against the default theme values. The result is a complete CSS rule wrapped in whatever selector you name, ready to paste into a stylesheet.
Variants are handled properly rather than dropped. A hover: prefix produces a second rule on .selector:hover. A responsive prefix such as md: produces a rule inside @media (min-width: 768px), using Tailwind's default breakpoints of 640, 768, 1024, 1280 and 1536 pixels. Focus, active, disabled, first, last and dark variants are supported the same way. The "variant rules emitted" counter tells you how many extra blocks were generated, which is usually the first hint of how much complexity a single class attribute was hiding.
In the reverse direction, paste plain CSS declarations and the tool matches each one against an index built from the same theme, returning the utility class that generates it. Declarations with no exact equivalent are returned as comments explaining why. The reverse direction is genuinely harder than the forward one, and the next sections explain exactly where it stops working.
How to Use It
- Choose a direction. Tailwind to CSS for reading and debugging existing markup, CSS to Tailwind when you are migrating a stylesheet into utilities.
- Paste your input. A raw class attribute for the forward direction, or a block of
property: value;declarations for the reverse. Braces and a selector line are tolerated and ignored. - Name a selector. The generated rule and any state variants are wrapped in it, so the output pastes straight into a stylesheet without editing.
- Click Convert. The hero shows how many tokens were resolved out of how many were found, and the four tiles break that down by declarations, variant rules, arbitrary values and unresolved items.
- Read the comments before you paste. Anything in the output beginning with a comment marker is a token the converter would not guess at.
How the Mapping Is Calculated
Tailwind's spacing scale is arithmetic, which makes most of the conversion mechanical rather than a lookup: a numeric spacing token is the number divided by four, expressed in rem. p-4 is 1rem, p-6 is 1.5rem, p-1.5 is 0.375rem. The special token px means exactly one pixel rather than a scale step, and fraction tokens such as w-1/2 resolve to percentages. That single rule covers padding, margin, width, height, gap, inset and the rest of the spacing-based families, which is the bulk of any real class attribute.
The non-arithmetic families are lookup tables taken from the default theme: the type scale and its bundled line heights, border radius steps, the box-shadow definitions, font weights, letter spacing, and the colour palette. Colours are the one place this tool is deliberately conservative — it ships a subset of the default palette rather than all of it, and a colour it does not hold is reported as unresolved instead of being approximated. An approximately correct brand colour is worse than an obvious gap, because it will survive review. The authoritative values for anything not covered here live in the Tailwind theme reference.
Arbitrary values in square brackets are expanded literally, with underscores converted back to spaces as Tailwind does: w-[37px] becomes width: 37px and grid-cols-[1fr_auto] becomes the corresponding template. These are counted separately because they are the tokens most likely to have been written to escape the design system, and they are worth a second look during review even when they convert perfectly.
What Cannot Round-Trip, and Why
This is the section that matters most, because the honest answer is that Tailwind to CSS is a function and CSS to Tailwind is not. The forward direction is deterministic: every utility has exactly one compiled output. The reverse direction is a search through a space where several inputs map to the same output, some outputs have no input at all, and some depend on configuration this page cannot see.
Four categories will not convert cleanly back into utilities. Arbitrary values round-trip only by re-wrapping them in brackets, which is syntactically valid but tells you nothing about whether a design-system token existed that you should have used instead — padding: 17px becomes p-[17px], and no tool can know you meant p-4. Variants cannot be recovered from a flat declaration list at all: a rule inside @media (min-width: 900px) has no utility equivalent unless 900px is a configured breakpoint, and a :hover rule only becomes hover: if the base rule is on the same element. Custom theme values are invisible here; if your config renames or extends the palette, spacing or breakpoints, the class this page suggests may not exist in your build. Anything structural — descendant selectors, pseudo-elements, keyframes, cascade layers, media queries other than width — has no utility form, because utilities describe one element's declarations and nothing else.
There is a fifth case worth naming separately: the space-x-* and space-y-* and divide-* families do not style the element they sit on. They generate a rule targeting sibling children, which means their compiled CSS is a different selector entirely. This converter reports them rather than folding them into your rule, because emitting those declarations on the parent would be flatly wrong. The mechanics of that behaviour are documented under Tailwind's space-between utilities.
Why text-sm Produces Two Declarations
Tailwind's font-size utilities set both font-size and line-height, which surprises people migrating out of Tailwind far more often than it should. text-sm is 0.875rem with a line height of 1.25rem, not just the size. If you convert a component to plain CSS and copy only the font sizes across, your vertical rhythm changes everywhere and the cause is genuinely hard to spot, because nothing about the size is wrong.
The same coupling explains a common confusion in the other direction: adding leading-relaxed after text-sm works because it comes later in the generated stylesheet, but the ordering that makes it work is Tailwind's, not your class attribute's. Class order in the HTML attribute has no effect on which rule wins — that is decided by specificity and source order in the compiled CSS. This is the same cascade behaviour described in MDN's reference on the CSS cascade, and it is why two conflicting utilities in one attribute produce a result that looks arbitrary until you read the compiled output.
Reading an Inherited Component
The most common real use of the forward direction is not migration at all. It is understanding a component someone else wrote. A class attribute with twenty-five utilities and four variant prefixes is dense to the point of being unreadable, and the fastest way to review it is to expand it into a rule and read it as CSS. Doing that regularly surfaces two things: duplicated declarations where two utilities in the same family fight each other, and variant blocks that only apply at one breakpoint and were probably never tested at the others.
It also gives you a number to reason about. "This padding is too tight" is an opinion; "this padding is 0.75rem and every other card in the system uses 1rem" is a review comment. When you need to convert those rem values to pixels against a specific root size, our px to rem converter does the arithmetic, and the CSS specificity calculator settles which of two competing rules actually wins.
Migrating a Stylesheet Into Utilities
The reverse direction is most useful as an audit rather than a bulk rewrite. Feed it the declarations from an existing component and read the two lists it returns: what mapped cleanly, and what did not. The clean matches are the parts of your stylesheet that already sit on the default scale, which usually turns out to be a comfortable majority. The unmatched ones are the interesting part — they are values that fell off the scale, either because a designer specified them precisely or because they accumulated by nudging over several years.
Those off-scale values are a decision, not a defect. Sometimes the right answer is to round to the nearest scale step and accept a one-pixel change nobody will see. Sometimes the value is load-bearing, like an optical alignment on an icon, and it should stay as an arbitrary value with a comment explaining why. What matters is that the choice is made deliberately rather than discovered later. If you are also compressing the resulting stylesheet for production, our CSS minifier handles that step, and the colour contrast checker verifies that any palette colour you swap in still meets accessibility thresholds against its background.
Layout Utilities Hide More Than They Show
Flexbox and grid utilities are where the forward conversion earns the most, because their names are short and their effects are not. flex alone is one declaration, but items-center justify-between is two more, and flex-1 expands to the full flex: 1 1 0% shorthand rather than the flex-grow: 1 most people assume. Grid column utilities are worse: grid-cols-3 compiles to repeat(3, minmax(0, 1fr)), and the minmax(0, 1fr) is not decoration. It is what stops grid items from refusing to shrink below their content width, which is the single most common cause of a grid that overflows its container.
Seeing that expansion is often the whole answer to a layout bug. If you are building the layout from scratch instead, our CSS grid generator and CSS flexbox generator produce the plain-CSS version directly, and you can paste the result back into this page's reverse direction to find the equivalent utilities.
Arb Digital designs and builds websites on a documented design system, with a component library your team can extend without the stylesheet drifting out of shape.
Web Design & Development Talk To Our TeamCommon Mistakes to Avoid
- Copying only the font size out of a type utility — Tailwind's size utilities set line height too, and dropping it changes vertical rhythm across the whole component.
- Assuming class order in the HTML decides the winner — it does not. Source order in the compiled stylesheet does, so two conflicting utilities give a result that looks random.
- Trusting a converted class when your config is customised — a renamed palette, an extended spacing scale or a custom breakpoint means the suggested class may not exist in your build.
- Folding space-x or divide utilities into the parent rule — they generate rules for sibling children, so their declarations belong on a different selector entirely.
- Treating an arbitrary value as a successful round trip —
p-[17px]is valid and still tells you the value never sat on the design scale in the first place.
Related Free Tools From Arb Digital
Convert scale values between units with the px to rem converter, resolve rule conflicts with the CSS specificity calculator, build layouts directly with the CSS grid generator or the CSS flexbox generator, produce fluid sizing with the CSS clamp generator, and compress the finished stylesheet with the CSS minifier. Every utility we publish is listed in the free online tools hub.
Frequently Asked Questions
The default theme scale used by Tailwind v3: a spacing scale of one quarter rem per step, breakpoints at 640, 768, 1024, 1280 and 1536 pixels, and the standard type, radius and shadow scales.
Yes, for declarations that match a default theme value exactly. Anything off the scale is returned as an arbitrary-value suggestion or as a comment, because guessing which scale step was intended would produce silently wrong markup.
Going forward they convert fine, into media queries and state selectors. Coming back is impossible from a flat declaration list, because a media query only maps to a prefix if its width matches a configured breakpoint and the base rule sits on the same element.
They are expanded literally, with underscores converted to spaces, and counted separately. They convert correctly but are flagged because they usually mean a value stepped outside the design system.
Because Tailwind's font-size utilities set a paired line height as well as the size. Copying only the font size out of a component is a common migration bug that changes spacing everywhere without looking wrong.
It reports them rather than converting them in place. Those families generate rules targeting sibling children, so their declarations belong on a different selector and adding them to the parent rule would be incorrect.
Only for values you have not changed. A custom palette, extended spacing scale or renamed breakpoint is invisible to this page, so verify any suggested class against your own configuration before using it.
No. Both conversions run entirely in your browser with no network requests, so pasting unreleased markup or a private stylesheet is safe.