PX to REM Converter
Convert every px value in a stylesheet to rem, or rem back to px, using your own base font size. Comments, strings, url() values and media-query breakpoints are left alone.
Rewrites units across a whole stylesheet. Comments, quoted strings, url() and @media/@container conditions are never touched: a query's rem is always measured against the browser default, not your root size.
What gets converted, and what is left alone
Every "after" below is this page's converter output from when the site was built. A blind find-and-replace on px breaks breakpoints, image names and comments; these cases show where this converter draws the line.
Ordinary values
Every px value is divided by the base size, 16px by default.
Before
h1{font-size:24px;margin:0 0 12px}
After
h1{font-size:1.5rem;margin:0 0 0.75rem}
A value that does not divide evenly
Values are rounded to four decimal places, so 13px is exactly 0.8125rem rather than a rounded 0.81rem.
Before
.a{font-size:13px}
After
.a{font-size:0.8125rem}
Inside calc()
Lengths inside calc() are converted like any other.
Before
.a{width:calc(100% - 20px)}
After
.a{width:calc(100% - 1.25rem)}
A negative margin
The sign is kept.
Before
.a{margin:-8px}
After
.a{margin:-0.5rem}
A 1px hairline
Left as 1px on purpose, so a hairline border stays one pixel wide whatever the root font size is.
Before
.a{border:1px solid red}
After
.a{border:1px solid red}
A media-query breakpoint
The breakpoint stays in px while the padding inside converts. In a media query, rem means the browser's default font size rather than your html font-size, so converting a breakpoint changes when the layout switches for anyone who has changed that setting.
Before
@media (min-width: 768px){.a{padding:32px}}
After
@media (min-width: 768px){.a{padding:2rem}}
url(), strings and comments
Nothing that only looks like a length is touched: file names, quoted text and comments come through unchanged.
Before
/* 8px grid */ .a{background:url(icon-16px.png)} .b::after{content:"10px"}
After
/* 8px grid */ .a{background:url(icon-16px.png)} .b::after{content:"10px"}
A different base size (base 10px)
With a 10px base (the html{font-size:62.5%} pattern), 24px becomes 2.4rem.
Before
h1{font-size:24px}
After
h1{font-size:2.4rem}
Back from rem to px (rem to px)
The same rules run in reverse.
Before
.a{font-size:1.5rem}
After
.a{font-size:24px}