The formula, written out
Both units end up as pixels in the browser. Convert rem to pixels first, then express those pixels as a share of the reference.
percent = (rem × root font size) ÷ reference × 100
With the default 16px root and a 16px parent, the two units line up one to one, so 1.5rem becomes 150%. The numbers drift apart the moment the parent changes. Three worked cases:
1.5rem, root 16, parent 16
24px ÷ 16px = 150%
1.25rem, root 16, parent 14
20px ÷ 14px = 142.86%
2.4rem, root 10, parent 12
24px ÷ 12px = 200%
Percent means a different thing on each property
This is where most rem to percent conversions go wrong. A percentage has no fixed reference. The property decides what it measures against, which is why the converter asks you to pick a mode before you type.
font-sizeThe parent element's computed font sizewidth, max-widthThe containing block's widthpadding, marginThe containing block's width, even for top and bottomheightThe containing block's height, and only when that height is setline-heightThe element's own font size, not the parent'stransform: translateThe element's own boxThe padding row surprises people. padding-top: 10% on a box inside a 600px column gives 60px of vertical space, whatever the box height. Use the container width mode for padding and margin, and enter the column width, not a height.
Line height is the other trap. line-height: 150% resolves against the element's own font size once, then the pixel result is inherited by children. A unitless line-height: 1.5 is almost always what you want instead, since children recalculate it from their own size.
When converting rem to percent is the right move
- Components that should follow their context. A badge inside a heading looks wrong at a fixed
0.75rem. At75%of the heading it scales with whatever heading it lands in. - Legacy stylesheets built on percentages. Older themes set every font size as a percent of the body. Matching that system keeps the cascade predictable instead of mixing two models in one file.
- Fluid layout widths. A sidebar specced at
20remon a 1280px layout is25%of the container. Switch to the width mode, enter the container size, and the column flexes with the viewport. - Email templates. Some mail clients handle percent font sizes more reliably than rem, since rem support depends on the client respecting the root element.
When to keep rem
Rem exists so sizes do not compound. Percent font sizes multiply down the tree. A list item at 90% inside another list item at 90% lands at 81% of the outer size, and three levels down body text gets small fast. If a value should look the same wherever it appears, such as body copy, spacing tokens or form controls, leave it in rem.
Both units respect a reader's browser text size setting, so accessibility is not a reason to pick one over the other. The difference is purely about which ancestor you want the size to track.
Limits of this converter
- It does not read your page. The reference size comes from you. If the number you enter differs from the computed value in DevTools, the result will be off by the same ratio.
- Batch mode uses one parent and one container. Real CSS targets elements with different parents. Paste rules that share a parent together, or run them in groups.
- No
calc()orclamp()parsing. Rem values inside those functions get converted as plain numbers, which is rarely correct. Review the output before shipping. - Height mode is left out on purpose. Percent heights depend on an explicit parent height, and that setup is rare enough that a guess would mislead more people than it helps.
All of the maths runs in your browser tab. Nothing you type or paste leaves the page. For the reverse direction, Percent to REM takes a percentage back to a root-relative value.