v145 · Web APIs · Pixel Units
Pixel Units
CSS pixels (logical pixels) versus physical pixels, how device pixel ratio relates them, and why using CSS pixels in the Layout Shift API produces fairer CLS scores across display densities.
The CSS specification defines CSS pixels as a logical unit independent of display density. Physical pixels are the actual hardware dots on the screen. On a 2× display, 1 CSS pixel = 2 physical pixels (in each dimension), so a 100×100px CSS box occupies 200×200 physical pixels.
the problem with physical pixels in CLS
| Scenario | Display (DPR) | Shift distance (CSS px) | Before Chrome 145 (physical px) | Chrome 145+ (CSS px) |
|---|---|---|---|---|
| Same visual shift, standard display | DPR = 1 | 100px | Score X | Score X |
| Same visual shift, Retina display | DPR = 2 | 100px | Score 4X (200 physical px per axis = 4× area) | Score X (same as standard) |
| Same visual shift, 3× display | DPR = 3 | 100px | Score 9X | Score X |
formula
// CLS shift fraction formula (unchanged, but inputs now in CSS px)
//
// impact fraction = (union of previousRect ∪ currentRect) / viewport
// distance fraction = (max shift distance) / (max of viewport width, height)
// layout shift score = impact fraction × distance fraction
//
// All areas and distances are in CSS pixels (Chrome 145+).
// This means identical visual shifts produce identical scores
// regardless of devicePixelRatio.
// Convert if you need physical pixels for other purposes:
const dpr = window.devicePixelRatio;
const physicalTop = source.currentRect.top * dpr; // CSS px → physical px
API fields affected
| Field | Interface | Change |
|---|---|---|
previousRect |
LayoutShiftAttribution |
Now in CSS pixels |
currentRect |
LayoutShiftAttribution |
Now in CSS pixels |
value |
LayoutShift |
Recalculated using CSS px (numerically different on high-DPI) |
hadRecentInput |
LayoutShift |
Unchanged |
see also
scenario focus
Select a scenario to focus its rendered example and summary.