v145 · CSS · Computation Reference
Computation Reference
How border-radius values are clamped, the shadow spread calculation, and which patterns were affected by the Chrome 145 fix.
The CSS specification requires that
border-radius values be clamped before use in other computations (including shadow edge shape). When the sum of adjacent radii exceeds the element dimension, all radii are scaled proportionally until they fit.
border-radius clamping algorithm
// CSS spec: border-radius clamping
// For an element of width W and height H:
//
// Horizontal: top-left-x + top-right-x ≤ W
// bottom-left-x + bottom-right-x ≤ W
// Vertical: top-left-y + top-right-y ≤ H (wait wrong, it's...)
// top-left-y + bottom-left-y ≤ H
// top-right-y + bottom-right-y ≤ H
//
// If any constraint fails, all radii are multiplied by:
// f = min(W / (tl-x + tr-x), W / (bl-x + br-x),
// H / (tl-y + bl-y), H / (tr-y + br-y))
//
// Example: 100×100 element with border-radius: 9999px
// Raw: 9999px per corner
// tl-x + tr-x = 19998 > 100 → f = 100/19998 ≈ 0.005
// Resolved: 9999 × 0.005 ≈ 50px per corner
// Result: effectively border-radius: 50px = 50% of width/height
shadow spread and the clamped radius
// Shadow spread (s) adjusts the shadow shape outward or inward.
// For a corner with resolved radius r, the spread shadow corner radius is:
//
// shadow-radius = max(0, r + s) when spread ≥ 0
// shadow-radius = max(0, r - |s|) when spread < 0
//
// Chrome 144 bug: used the unclamped r in this formula.
// Example: 100×100px element, border-radius: 9999px, spread: 4px
// Chrome 144: shadow-radius = 9999 + 4 = 10003px (wrong shape)
// Chrome 145: shadow-radius = 50 + 4 = 54px (correct — uses clamped 50px)
// This matters most when spread is large relative to the element size,
// or when the shadow ring (spread=0, blur=0) is used as an outline.
affected patterns
/* Patterns affected by the Chrome 145 fix */
/* 1. Circular elements */
.avatar { border-radius: 50%; box-shadow: 0 0 0 2px white; }
/* 2. Pill buttons */
.btn { border-radius: 100vmax; box-shadow: 0 2px 6px rgba(0,0,0,0.2); }
/* 3. Large fixed radius */
.card { border-radius: 9999px; box-shadow: inset 0 0 0 1px rgba(0,0,0,0.1); }
/* 4. Negative spread on rounded elements */
.badge { border-radius: 50%; box-shadow: 0 0 0 -1px rgba(0,0,0,0.5); }
/* Unaffected: elements where border-radius does not trigger clamping */
.small-radius { border-radius: 4px; } /* stays as 4px — no clamping */
see also
scenario focus
Select a scenario to focus its rendered example and summary.