14px text with a 16 base
- Input
- 14px ÷ 16
- Expected output
- 0,875rem
A common size for secondary text; the result has three exact decimals.
convert px to rem
Converting px to rem is a division: pixels divided by the root element font-size. Browsers default to 16px, so 1rem is 16px. The tool below does the math, shows the steps, accepts another base and swaps px for rem across a whole CSS block.
A common size for secondary text; the result has three exact decimals.
Half again as large as 1rem body text.
This is the html at 62.5% case on the browser default: the base changes, and so does the rem number.
Multiplying by the base returns the value in pixels.
Divide the pixels by the root font-size. With a 16px base: 24px ÷ 16 = 1.5rem, 14px ÷ 16 = 0.875rem and 10px ÷ 16 = 0.625rem. To go the other way, multiply: 1.25rem × 16 = 20px.
It depends on the html element font-size. In the default browser setting it is 16px, so 1rem = 16px. If the user raises the browser default font size or your CSS changes the root, the value changes.
No. Font sizes and spacing that should follow the user reading preference are good candidates. Hairline borders, shadows and image dimensions usually stay in px. Review the result instead of converting blindly.
Dividing by 16 is only exact for multiples of 1/16 of a pixel. 13px gives 0.8125rem, 11px gives 0.6875rem and 10px gives 0.625rem; roots such as 12px or 14px produce repeating decimals in many cases. The tool lets you choose 0 to 6 decimals and trim trailing zeros.
Here, % means a percentage of the reference font-size (as in font-size: 150%). In width, padding and other properties, % refers to something else, so this conversion does not apply to them.
To rem: 24 ÷ 16 = 1.5 rem
Paste a CSS block and swap every value in one unit for another, leaving everything else alone. Comments, strings, url() and numbers inside names (classes, variables, colors) are left untouched.
Paste a CSS block above to convert. The result shows up here instantly.
Quick reference with a root font-size of 16px. Click a rem value to copy it. The Tailwind column shows the step n where n × 0.25rem gives the same size.
| px | rem | Tailwind (n) |
|---|---|---|
| 4px | 1 | |
| 6px | 1.5 | |
| 8px | 2 | |
| 10px | 2.5 | |
| 12px | 3 | |
| 14px | 3.5 | |
| 16px | 4 | |
| 18px | - | |
| 20px | 5 | |
| 24px | 6 | |
| 28px | 7 | |
| 32px | 8 | |
| 36px | 9 | |
| 40px | 10 | |
| 48px | 12 | |
| 56px | 14 | |
| 64px | 16 | |
| 72px | - | |
| 80px | 20 | |
| 96px | 24 | |
| 112px | 28 | |
| 128px | 32 |
| n | rem | px |
|---|---|---|
| 0 | 0 | 0 |
| 0.5 | 0.125 | 2 |
| 1 | 0.25 | 4 |
| 1.5 | 0.375 | 6 |
| 2 | 0.5 | 8 |
| 2.5 | 0.625 | 10 |
| 3 | 0.75 | 12 |
| 3.5 | 0.875 | 14 |
| 4 | 1 | 16 |
| 5 | 1.25 | 20 |
| 6 | 1.5 | 24 |
| 7 | 1.75 | 28 |
| 8 | 2 | 32 |
| 9 | 2.25 | 36 |
| 10 | 2.5 | 40 |
| 11 | 2.75 | 44 |
| 12 | 3 | 48 |
| 14 | 3.5 | 56 |
| 16 | 4 | 64 |
| 20 | 5 | 80 |
| 24 | 6 | 96 |
| 28 | 7 | 112 |
| 32 | 8 | 128 |
| 36 | 9 | 144 |
| 40 | 10 | 160 |
| 44 | 11 | 176 |
| 48 | 12 | 192 |
| 52 | 13 | 208 |
| 56 | 14 | 224 |
| 60 | 15 | 240 |
| 64 | 16 | 256 |
| 72 | 18 | 288 |
| 80 | 20 | 320 |
| 96 | 24 | 384 |
In Tailwind, spacing is n × 0.25rem (the --spacing variable defaults to 0.25rem), so p-4 is 1rem. The px column follows the root font-size set above. The listed steps are the classic scale; the table on the left shows - when the size does not land on one of them.
Generate a clamp() that grows the size linearly between two viewports and locks at the ends. The output uses rem + vw, with the formula shown step by step.
The maximum size is less than twice the minimum. Adrian Roselli notes that with vw or a clamped size the user may be unable to reach 200% (WCAG 1.4.4, level AA), and suggests never letting the maximum fall below twice the base size. This does not guarantee conformance either way: test at 200% and 300% zoom.
1) Slope = (24 - 16) ÷ (1280 - 320) = 0.008333 font px per screen px
2) In vw: 0.008333 × 100 = 0.8333vw
3) Fixed term = 16 - 0.008333 × 320 = 13.3333px = 0.8333rem (÷ 16)
4) Preferred value = 0.8333rem + 0.8333vw, locked between minimum and maximum by clamp()
Pure vw ignores the user font-size preference and can break text zoom. That is why the fixed term is in rem: it follows the preference, and only the part that grows with the screen uses vw.
| Viewport | px | rem |
|---|---|---|
| 320px | 16 | 1 |
| 375px | 16.46 | 1.029 |
| 414px | 16.78 | 1.049 |
| 768px | 19.73 | 1.233 |
| 1024px | 21.87 | 1.367 |
| 1280px | 24 | 1.5 |
| 1440px | 24 | 1.5 |
| 1920px | 24 | 1.5 |
Fluid typography changes size with the screen
Size now: 20px (1.25rem)
The box uses the same formula with cqw (container unit) in place of vw, so the browser resolves the clamp() for real. On narrow screens the box cannot exceed the screen width.
Each step is the base size multiplied by the ratio raised to the step number. Pick a ratio, see the scale in rem and px, and export it as CSS variables or Tailwind.
Samples stop at 72px to fit the screen; the table values are the real ones.
:root {
--text-7xl: 5.9605rem;
--text-6xl: 4.7684rem;
--text-5xl: 3.8147rem;
--text-4xl: 3.0518rem;
--text-3xl: 2.4414rem;
--text-2xl: 1.9531rem;
--text-xl: 1.5625rem;
--text-lg: 1.25rem;
--text-base: 1rem;
--text-sm: 0.8rem;
--text-xs: 0.64rem;
}Convert breakpoints from px to em and generate the media queries. Paste a list (one per line, or comma separated) in px, em or rem.
| px | em | Condition | Copy |
|---|---|---|---|
| 640 | 40 | (min-width: 40em) | |
| 768 | 48 | (min-width: 48em) | |
| 1024 | 64 | (min-width: 64em) | |
| 1280 | 80 | (min-width: 80em) | |
| 1536 | 96 | (min-width: 96em) |
@media (min-width: 40em) {
/* ... */
}
@media (min-width: 48em) {
/* ... */
}
@media (min-width: 64em) {
/* ... */
}
@media (min-width: 80em) {
/* ... */
}
@media (min-width: 96em) {
/* ... */
}The Media Queries specification says relative units in media queries are based on the initial value, never on declarations in the page. In HTML, em is the initial font-size defined by the browser or the user preferences, not what your CSS declares.
Practical consequence: em and rem are the same inside a media query, and an html with font-size: 62.5% does not change the breakpoints. If the user raises the default font size, em breakpoints rise with it and the layout switches earlier, which is usually what you want for larger text.
Range syntax (width >= 48em, width < 48em) removes the need for the 0.02px trick, because the upper bound is exclusive. It only works in recent browsers; check support before using it in production.
rem is a multiple of the root element font-size, which by default is the font size set in the browser (16px in the default setting). If the person raises that size in settings, everything in rem grows with it. A px value stays fixed, whatever the preference. Pick the browser default below and compare.
Does the text adapt to the reader?
font-size: 16px results in 16px, always
Does the text adapt to the reader?
font-size: 1rem results in 16px
Browser zoom (Ctrl and +) enlarges the whole page, including what is in px. The font-size preference, available in browsers like Chrome, Edge and Firefox, only affects what is relative (rem, em, %).