rem vs em vs px: which unit should I use?
Use rem for font sizes, spacing and layout, because it respects the reader's browser font-size setting. Use em when a value should scale with the element's own font size. Use px only for borders and shadow offsets.
#rem
Relative to the root font size — 16px by default, but larger if the reader has configured bigger text.
:root { --s-4: 1rem; --text-lg: 1.125rem; }A layout built in rem grows with that preference. A layout built in px ignores it entirely, which is an accessibility failure for anyone who needs larger type.
#em
Relative to the current element's font size. Perfect for padding that should stay proportional to the text inside it:
.button {
font-size: 1.125rem;
padding: 0.6em 1.2em; /* scales with the button's own text */
border-radius: 0.4em;
}Change the font size and the padding follows. That is exactly what you want for a component that comes in several sizes.
#px
Correct for things that should not scale:
border: 1px solid;
box-shadow: 0 1px 2px rgb(0 0 0 / 0.1);A 1px hairline should stay a hairline. Scaling it to 1.5px produces a blurry line.
#ch and other useful ones
.prose { max-width: 65ch; } /* ~65 characters — the readable line length */ch is the width of the "0" glyph. It is the most direct way to control measure, which is one of the highest-impact typography settings there is.
Also worth knowing: vh/vw for viewport-relative sizing, and dvh for the dynamic viewport height that accounts for mobile browser chrome appearing and disappearing.