v158 · css · values & units

Background layer count independence

Write background-position: 0 0, 10px 10px with a single background-image and pre-158 Chrome would compute that list down to one entry — your second value was gone from getComputedStyle, from inheritance, from animations. CSS Values 4 Appendix A says truncating and repeating to the image count is used-value behaviour only: “The computed values of the coordinating list properties are not affected by such truncation or repetition.” Chrome 158 finally keeps the author’s list — Firefox always did, Safari shipped it in STP 246, and rendering does not change at all.

concepts

  1. Computed list probe

    The canonical observation. Dial the number of background images and the number of background-position entries independently, watch the painted stage, and read the computed list back — preserved on Chrome 158, truncated or repeated to the image count on everything older.

  2. Layer-count lab

    All seven coordinated background-* longhands at deliberately mismatched lengths in one inspection table: author length vs computed length vs used layer count — plus Appendix A’s other observable, the background shorthand serialising to the empty string when lists mismatch, and a labelled mask-position comparison.

  3. Layer editor round-trip

    Why tools care: a miniature background-layer editor that saves its state by reading getComputedStyle back. Toggle a layer’s image off and re-save — pre-158 engines silently destroy the hidden layers’ positions and sizes; Chrome 158 round-trips losslessly.

  4. Inheritance & used value

    What does not change: two painted stages prove the used values still truncate and repeat, so no site renders differently. What does: background-position: inherit now passes the full list to a child with more images, and a transition interpolates the preserved entries — both read live.

why it shipped

The CSSWG re-discussed Appendix A in 2025 (issue #12791) and resolved the long-specified behaviour should stand; the tests were updated and Chrome was by then the only engine still equalising computed lists. Truncating at computed-value time is lossy in every place computed values flow: getComputedStyle readbacks, inherit, custom-property-free theming, and list interpolation in transitions and animations. Keeping the author’s list makes style readback honest while changing zero pixels, because the truncation/repetition still happens where it always mattered — at used-value time.

the API

el.style.backgroundImage = "linear-gradient(…)";          /* ONE image  */
el.style.backgroundPosition = "0px 0px, 10px 10px";       /* TWO entries */

getComputedStyle(el).backgroundPosition
/* Chrome ≤157: "0px 0px"            — second entry destroyed   */
/* Chrome 158+: "0px 0px, 10px 10px" — computed list preserved  */

/* …while the USED value (what paints) is still truncated to the
   image count, so rendering is identical in both. */

references