A layout can look calm on a desktop and awkward on a phone without any single rule being obviously wrong. The heading is too large. The card padding feels heavy. A button wraps in a strange place. The design was not broken exactly; the units were too rigid for the range of screens and user settings it had to survive.
CSS units decide how sizes respond to context. Pixels, rems, ems, viewport units, and percentages each answer a different question. Good responsive design is not about replacing every px with rem. It is about choosing the unit that matches the job.
BlinkCalc's Pixel Converter helps convert px, rem, em, pt, vw, and vh values, but the real value comes from knowing why you would choose one unit over another.
What px means
px stands for CSS pixel. It is the most familiar unit because it feels concrete:
.button {
padding: 12px 16px;
border-radius: 8px;
}
A CSS pixel is not always one physical screen pixel. Modern devices, browser zoom, and device pixel ratios abstract that away. Still, px behaves like a fixed design unit inside CSS.
Pixels are useful for:
- Borders
- Hairline dividers
- Icon sizes
- Small fixed gaps
- Canvas measurements
- Precise visual details
Pixels are less flexible for body text and large layout spacing because they do not naturally respond to user font-size preferences. A design made entirely from fixed pixel sizes may be harder to adapt.
What rem means
rem means root em. It is based on the font size of the root element, usually the html element. In many browsers, the default root font size is 16px, unless the user or site changes it.
If the root is 16px:
| rem | px equivalent |
|---|---|
| 0.5rem | 8px |
| 0.75rem | 12px |
| 1rem | 16px |
| 1.5rem | 24px |
| 2rem | 32px |
This makes rem useful for typography and spacing systems:
html {
font-size: 100%;
}
.article-title {
font-size: 2rem;
margin-bottom: 1rem;
}
If a user increases their preferred font size, rem-based text and spacing can scale more naturally. Implementation still matters: relative units support accessibility better than fixed pixel-only design in many cases, but they do not guarantee an accessible interface by themselves. Line length, contrast, zoom behavior, overflow, and layout flexibility matter too.
What em means
em is based on the font size of the current element or its inherited context. That makes it powerful and sometimes surprising.
.badge {
font-size: 0.875rem;
padding: 0.4em 0.7em;
}
In this example, the padding scales with the badge's own text size. If the badge text becomes larger, the padding grows with it. That is useful for components where spacing should relate closely to the text inside.
The surprise appears with nesting. If a parent has font-size: 1.25em and a child also has font-size: 1.25em, the child compounds from the parent. That can be useful in a controlled component, but it can create unexpected size jumps in deeply nested content.
Use em when local scaling is the goal. Use rem when you want consistency from the root.
What vw and vh mean
vw means viewport width. vh means viewport height. One vw is 1% of the viewport width. One vh is 1% of the viewport height.
.hero {
min-height: 70vh;
padding-inline: 6vw;
}
Viewport units are useful for layout areas that should relate to the browser window, such as full-screen sections, fluid spacing, and responsive media frames.
They can be risky for text if used without limits. A heading set to 8vw may look reasonable on a phone and huge on a wide monitor. A small viewport can make text too tiny. CSS functions such as clamp() often make viewport units safer:
.headline {
font-size: clamp(2rem, 4vw, 4.5rem);
}
That says: do not go below 2rem, prefer 4vw when it fits, and do not exceed 4.5rem.
Absolute vs relative units
Pixels are often described as absolute. Rem, em, vw, vh, and percentages are relative. The distinction is practical rather than moral. Absolute units are predictable. Relative units adapt.
Good interfaces usually use both:
| Use case | Often suitable |
|---|---|
| Body font size | rem |
| Component padding | rem or em |
| Border width | px |
| Icon size | px, rem, or em |
| Page max width | rem, px, or ch |
| Full-height panel | vh or dynamic viewport units |
| Fluid hero spacing | clamp with vw |
| Rounded corners | px or rem |
The unit should express the relationship you want. If spacing should grow with text, use relative text-based units. If a border should remain a thin line, px may be fine.
Typography and accessibility
Typography is where unit choices become noticeable. Fixed pixel text can ignore user preferences unless browser zoom compensates. Rem-based type is easier to connect to the root font size and tends to behave better in scalable systems.
A practical type scale might look like:
:root {
font-size: 100%;
}
body {
font-size: 1rem;
line-height: 1.6;
}
h1 {
font-size: clamp(2rem, 4vw, 3.5rem);
line-height: 1.1;
}
Notice that the body uses rem, while the heading uses a bounded fluid value. The heading can respond to viewport width without becoming unlimited.
Accessibility is not only unit choice. Text must also reflow when zoomed, maintain readable contrast, preserve line height, and avoid clipping. A rem-based layout can still fail if containers have fixed heights or hidden overflow.
Spacing systems
Spacing systems keep designs consistent. A common approach is to define spacing tokens based on rem:
:root {
--space-1: 0.25rem;
--space-2: 0.5rem;
--space-3: 0.75rem;
--space-4: 1rem;
--space-6: 1.5rem;
--space-8: 2rem;
}
Then components use tokens instead of random values:
.card {
padding: var(--space-6);
gap: var(--space-4);
}
This is easier to maintain than mixing 13px, 22px, and 37px across a codebase. It also helps design and development teams speak the same sizing language.
Pixels still have a place. A 1px border, 2px focus outline, or 8px radius may be perfectly reasonable. Consistency matters more than pretending one unit solves everything.
Choosing units by component
The easiest way to choose units is to think about the component's behavior.
| Component part | Sensible unit choice | Reason |
|---|---|---|
| Body copy | rem | Follows the root text scale |
| Button padding | em or rem | Can scale with the label or system |
| Icon inside text | em | Matches surrounding text size |
| Card max width | rem or px | Keeps readable line length |
| Divider border | px | Should stay visually thin |
| Hero spacing | clamp with rem and vw | Can be fluid but bounded |
| Modal height | viewport units with limits | Relates to available screen space |
This is not a rigid table. It is a decision aid. A design system may choose rem for icon sizes to keep all icons on a consistent scale. Another may use em so icons grow with button text. Either can work if the rule is intentional and tested.
Problems often appear when a component mixes units without a reason. A card with font-size: 14px, padding: 1.375rem, gap: 9px, and a fixed height: 180px may be hard to maintain because each value responds differently.
Responsive design examples
Consider a card grid. On desktop, each card has room for generous padding. On mobile, the same padding may crowd the content.
.card {
padding: clamp(1rem, 2vw, 1.5rem);
border-radius: 0.75rem;
}
The padding can move between 1rem and 1.5rem based on viewport width. It will not shrink into nothing or grow wildly.
For a button with text and an icon:
.button {
font-size: 1rem;
padding: 0.65em 1em;
gap: 0.5em;
}
The padding and gap follow the button's font size. If a compact variant changes the font size, the surrounding space adjusts proportionally.
For a full-screen layout:
.panel {
min-height: 100vh;
}
On some mobile browsers, classic vh can behave awkwardly as browser controls appear and disappear. Newer dynamic viewport units can help where supported, but test the exact behavior in your target browsers.
Breakpoints and fluid values
Breakpoints are still useful. Fluid units do not remove the need to change layout when the available space changes. A three-column desktop grid may need to become two columns, then one column. No unit conversion can make three cramped columns readable on a narrow screen.
Use units and breakpoints together:
.cards {
display: grid;
gap: clamp(1rem, 2vw, 1.5rem);
grid-template-columns: repeat(3, minmax(0, 1fr));
}
@media (max-width: 48rem) {
.cards {
grid-template-columns: 1fr;
}
}
The gap changes fluidly, while the layout changes at a deliberate breakpoint. That combination is usually more reliable than trying to make every value scale continuously.
Also test long words, translated labels, user zoom, and increased text size. Responsive design is not only about screen width. It is about content and user settings too.
A small before-and-after
Here is a rigid version of a mobile-unfriendly card:
.promo-card {
width: 420px;
height: 240px;
padding: 32px;
font-size: 18px;
}
It may look fine in a desktop mockup. On a narrow screen, the fixed width can overflow. If the text wraps, the fixed height can clip content. If the user increases font size, the card has little room to adapt.
A more flexible version might be:
.promo-card {
width: min(100%, 26rem);
min-height: 15rem;
padding: clamp(1rem, 3vw, 2rem);
font-size: 1rem;
}
The card now respects the container width, keeps a reasonable maximum, allows height to grow, and uses bounded fluid padding. This does not make the component perfect, but it removes several predictable failure points.
Testing unit choices
You can catch many unit problems with a short manual pass:
- Zoom the browser to 200% and check whether text clips.
- Increase the default font size if the browser allows it.
- Resize the viewport from narrow to wide slowly.
- Test a long button label and a long card title.
- Check a dense component, such as a table toolbar or settings panel.
- Confirm focus outlines and borders still look intentional.
The goal is not to prove every possible device is perfect. It is to reveal values that are too fixed, too fluid, or tied to the wrong context. If one card needs a fixed height because of a design constraint, make that constraint deliberate and test the longest expected content inside it.
When a value fails, change the relationship rather than only changing the number. A 320px sidebar that overflows may need minmax() or a breakpoint, not 300px. A 6vw heading that gets too large may need clamp(), not a slightly smaller viewport value. The fix usually comes from asking what the size should depend on.
That question keeps responsive fixes practical overall instead of turning them into endless tiny adjustments.
Worked example: converting px to rem
Assume the root font size is 16px. To convert pixels to rem:
rem = px / root font size
So:
| px | rem |
|---|---|
| 10px | 0.625rem |
| 14px | 0.875rem |
| 18px | 1.125rem |
| 24px | 1.5rem |
| 40px | 2.5rem |
If a design specifies a 24px heading and your base is 16px, use 1.5rem. If the base is 20px, 24px becomes 1.2rem. The base matters.
Open the Pixel Converter when you need quick conversions or want to compare px, rem, em, and viewport units without doing the arithmetic repeatedly.
Finishing visual details
Unit choices affect structure, but small visual tools help polish components after the scale is right. The CSS Border Radius Generator is useful for testing corner values on cards, buttons, and media frames. The Box Shadow Generator helps tune depth without guessing blur and spread values. The CSS Gradient Generator can help build backgrounds, but check contrast if text sits on top.
These are finishing tools, not substitutes for responsive structure. A beautiful shadow will not fix a heading that overflows on mobile.
Common mistakes
Using px for every text size. It can make scaling and user preferences harder to support.
Using vw for text without limits. Fluid text needs minimum and maximum bounds.
Forgetting em compounds. Nested em-based font sizes can multiply unexpectedly.
Changing the root font size casually. It affects every rem-based value in the system.
Locking containers with fixed heights. Scalable text needs room to wrap and reflow.
Converting values without understanding the base. Px-to-rem conversion depends on the root font size.
Treating units as a design system by themselves. Tokens, layout rules, and testing still matter.
FAQ
What is the difference between px and rem? Px is a fixed CSS unit. Rem is relative to the root font size, so it can scale with the root setting.
When should I use em? Use em when spacing or sizing should relate to the current element's font size, such as button padding.
What do vw and vh mean? They are viewport units. 1vw is 1% of viewport width, and 1vh is 1% of viewport height.
Are rem units always better than px? No. Rem is often better for type and scalable spacing, while px can be appropriate for borders, icons, and precise details.
How do I convert px to rem? Divide the pixel value by the root font size. With a 16px root, 24px equals 1.5rem.
Can relative units improve accessibility? They can support user font-size preferences better than fixed pixel-only design, but accessible implementation also requires reflow, contrast, readable line height, and testing.
Should responsive design use only viewport units? No. Viewport units are useful, but they often need clamp(), rems, percentages, and layout breakpoints around them.
Choose the relationship first
CSS units are small decisions that add up. Before choosing a unit, ask what the size should relate to: the root font size, the local text size, the viewport, or a fixed visual detail. That question leads to better choices than memorizing a universal rule, and it makes responsive layouts easier to maintain.