Command Palette

Search for a command to run...

Hectal
PHASE 3Beginner ~21 min· topic 1 of 7

Topic 3.1

Pixels and Absolute Units

In one line

A CSS pixel (px) is an agreed reference size, not one dot on your screen; the browser maps it to real device pixels using the device pixel ratio, and every other absolute unit (in, cm, mm, pt, pc) is a fixed number of CSS pixels.

Think of it like this

A recipe that says "one cup of rice". Your cup and your grandmother's cup are not the same physical size, but everyone agrees what "one cup" means, so the recipe works in every kitchen. A CSS pixel is like that cup: an agreed amount that every browser understands, even though each screen is built from different-sized dots.

Words you'll meet

New words in this topic, in plain English. Come back here whenever one feels fuzzy.

Value
The part of a CSS declaration after the colon, like red or 16px.
Length
A value that measures a distance: a number plus a unit, like 20px or 1.5rem.
Unit
The letters after the number that say what the number counts, like px or cm.
CSS pixel (px)
The basic CSS length. An agreed size, about one dot on a 96 dpi screen seen from arm's length.
Device pixel
One real dot of light on the screen hardware. Sharp screens have many of them per CSS pixel.
Device pixel ratio (DPR)
How many device pixels fit across one CSS pixel. 1 on old monitors, 2 or 3 on sharp screens.
Absolute unit
A unit with a fixed size that never depends on anything else on the page: px, in, cm, mm, Q, pt, pc.
Print stylesheet
CSS that only applies when the page is printed, written inside @media print { ... }.

Step by step

01A length is a number glued to a unit

Write the number and the unit with nothing between them. 0 is the one length that needs no unit, because zero of anything is zero.

A broken length makes the whole declaration invalid, and the browser skips it as if it were not there.

style.csswhole filecss
.box {
  width: 200px;     /* valid */
  margin: 0;        /* valid: zero needs no unit */
  padding: 16 px;   /* invalid: space between number and unit, ignored */
  height: 120;      /* invalid: no unit, ignored */
}

02One CSS pixel, several device pixels

On a DPR 2 laptop, a 100px wide box covers 200 device pixels across (and 200 down). The box looks the same size as on a DPR 1 screen; it is only sharper, because it is drawn with four times as many dots.

This is why a photo that is exactly 100 image pixels wide looks soft on a sharp screen inside a 100px box: the browser has to stretch 100 dots of data over 200 device pixels. The HTML course shows how srcset sends a bigger image to those screens.

One CSS pixel, several device pixelsdiagram
Rendering diagram…

03Every absolute unit is a fixed number of pixels

The browser converts all absolute units to pixels before layout. 1in, 2.54cm, 25.4mm, 72pt and 6pc are all exactly 96px. DevTools shows the converted value in the Computed pane.

units.csswhole filecss
/* all five boxes are exactly 96px wide */
.a { width: 96px; }
.b { width: 1in; }
.c { width: 2.54cm; }
.d { width: 72pt; }
.e { width: 6pc; }

04Use real-world units where they are real: print

When the page is printed, the browser knows the paper size, so cm, mm and pt match reality. That makes them the natural choice inside a print stylesheet.

print.csswhole filecss
@media print {
  body { font-size: 11pt; }
  @page { margin: 2cm; }
  nav, .ads { display: none; }
}

05Choose px for fixed details, not for text

Keep px for things that should stay the same size whatever the text size: borders, hairlines, shadow offsets. For font sizes and most spacing, use rem (next topic), which follows the reader's chosen default size.

Try it yourself

  1. 1

    Predict, then measure

    In the first example, add a sixth box with class mm and width: 25.4mm, and add its text 25.4mm. Before you run it, predict what the console prints for it. Then run and check.

  2. 2

    Break the length on purpose

    Change .cm { width: 2.54cm; } to .cm { width: 2.54 cm; } (with a space). Predict the box's width first. Then run: the declaration is ignored, the box falls back to its default width (it stretches to the text), and the console no longer prints 96px for it.

  3. 3

    Watch the ratio change with zoom

    In the second example, zoom the browser to 200% and press Run. The ratio doubles, because each CSS pixel is now drawn with twice as many device pixels across.

Code & diagrams

Five absolute units, one size New tab

All five boxes line up. getComputedStyle shows the size the browser really used, always in px.

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

96px = 96px
1in = 96px
2.54cm = 96px
72pt = 96px
6pc = 96px
Your screen's device pixel ratio and hairlines New tab

Zoom the page in and out (Ctrl/Cmd and + or -) and run again: the ratio changes. On a DPR 2 or 3 screen the 0.5px line is thinner than the 1px one; on DPR 1 they look the same.

Preview

Press Run to see the page.

Console

Nothing logged yet.
Absolute units and their pixel valuescss
/* Unit   Name               In CSS pixels */
/* px     CSS pixel          1px            */
/* in     inch               96px           */
/* cm     centimetre         ~37.8px        */
/* mm     millimetre         ~3.78px        */
/* Q      quarter-millimetre ~0.945px       */
/* pt     point (1/72 in)    ~1.333px       */
/* pc     pica (12pt)        16px           */

Break it on purpose

Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.

Break #1

Forget the unit

Write width: 300; on a box instead of width: 300px;.

terminal
$ DevTools → Elements → Styles
── what you'll see ──
width: 300; is crossed out with a yellow warning triangle ("Invalid property value"), and the box keeps its default width.

Break #2

Expect 1cm to be a real centimetre on screen

Make a box width: 10cm and hold a ruler against your monitor.

terminal
$ Hold a ruler to the screen
── what you'll see ──
The box is not 10 cm wide; on most screens it is noticeably smaller or bigger.

Myth vs fact

Myth

One CSS pixel is one dot on my screen.

Fact

Only when the device pixel ratio is 1. On sharp screens one CSS pixel covers 2×2 or 3×3 device pixels (or a fraction when zoomed).

Myth

px is a bad unit and should never be used.

Fact

px is perfect for borders, shadows and other fixed details. The problem is only using it for font sizes, which ignores the reader's default font-size setting.

Myth

1in on screen is one real inch.

Fact

It is always 96 CSS pixels. Its physical size depends on the screen. It matches a real inch only when printing.

Pro corner

Extra depth for experienced readers. New to this? Skip it for now and come back later.

  • ▸

    The spec allows two ways to anchor absolute units: to the reference pixel (screens: px is the anchor, physical units derived from it) or to physical units (print: in is the anchor). Browsers use the first on screen, which is why 1in is always exactly 96px there.

  • ▸

    Chromium lays out in fixed-point LayoutUnits of 1/64 px, so very long chains of fractional sizes can show tiny rounding differences between browsers. Avoid layouts that depend on sub-pixel exactness (for example, columns that must add up to precisely 100%).

  • ▸

    window.devicePixelRatio also changes when the user zooms or drags the window to another monitor. matchMedia("(resolution: 2dppx)") and the resolution media feature let CSS react to it, and image-set() picks a background image per resolution.

  • ▸

    Since CSS Values 4, border widths and outline widths snap to whole device pixels (rounded down, but never below one device pixel when non-zero). That is the rule behind the 0.5px hairline trick.

Remember this

  1. 1

    A CSS value is what comes after the colon in a declaration. A length is a value that measures distance: a number joined to a unit with no space, like 16px or 2.5cm. The only length you may write without a unit is 0. If you put a space (16 px) or forget the unit (width: 200), the declaration is invalid and the browser ignores it, as you saw in Topic 0.3 — CSS Syntax.

  2. 2

    **px is the CSS pixel. The spec defines it as a reference pixel**: roughly the size one pixel appears on a 96 dots-per-inch screen held at arm's length. It is a unit of *layout*, not of hardware. A 100px wide box looks about the same size on a cheap monitor, a 4K laptop and a phone, even though those screens pack very different numbers of real dots into that space.

  3. 3

    The real dots of light on a screen are device pixels (also called physical pixels). The number of device pixels used for one CSS pixel is the device pixel ratio (DPR). An old office monitor has a DPR of 1. Most laptops with sharp screens have 2. Many phones have 3. JavaScript can read it as window.devicePixelRatio. Zooming the page changes it too: at 200% zoom on a DPR 1 monitor it becomes 2.

  4. 4

    The other absolute units are fixed multiples of the CSS pixel: 1in = 96px, 1cm = 96px / 2.54 ≈ 37.8px, 1mm ≈ 3.78px, 1Q (quarter-millimetre) = 0.25mm, 1pt (point) = 1/72in ≈ 1.333px, and 1pc (pica) = 12pt = 16px. On a screen, 1cm is almost never one real centimetre, because the browser cannot know the physical size of your screen. These units are mainly useful in print stylesheets (@media print), where paper sizes are real.

  5. 5

    **When px is the right choice:** borders (1px solid), outline and shadow offsets, tiny fixed details like a 2px focus ring gap, and anything that should not grow with the text. When it is not: font sizes. If you set font-size: 14px, a reader who raised the default font size in their browser settings (because they have low vision) gets ignored. Browser zoom still works, but the setting does not. Relative units (Topic 3.2) fix that.

  6. 6

    Lengths can be fractions, like 33.333px. The browser keeps the fractions while it works out the layout, then snaps edges to whole device pixels when it paints, so lines stay crisp. Border widths are rounded down to whole device pixels, but any border above zero is drawn at least one device pixel thick. That is why 0.5px shows a thin hairline on a DPR 2 phone but a normal 1px line on a DPR 1 monitor.

Explain it without notes

01

What is a CSS pixel, and how is it different from a device pixel?

02

What does the device pixel ratio tell you, and what changes it?

03

Why are cm and in unreliable on screens but fine in print?

04

When is px the right unit, and when should you avoid it?

Practice

01

Write CSS for a .stamp box that is exactly 2in wide and 1in tall, with a 2pt solid border. What are its sizes in pixels?

02

Write a print stylesheet that sets the body text to 12pt, page margins to 1.5cm, and hides any element with class no-print.

Trade-offs

  • ↔

    px is predictable and easy to read in DevTools, but px font sizes ignore the reader's default font size. rem respects it at the cost of a little mental maths.

  • ↔

    Physical units are accurate in print but misleading on screen; keep them inside @media print.

Done when you can

  • I can write a valid length and spot an invalid one (missing unit, extra space).

  • I can explain the difference between a CSS pixel and a device pixel.

  • I can read the device pixel ratio and say what changes it.

  • I know the pixel value of in, cm, mm, pt and pc.

  • I can say when px is right and when to use a relative unit instead.