v138 · css

Grid Layout Calc

Chrome 138 relaxes calc() multiplication and division so a <length> divided by another <length> can produce a real unitless number. @property declarations constrain the controls to typed lengths: the cards use height: calc(var(--item-h) - var(--gap-size)), while their number opacity uses 100cqw / var(--col-min-w) as a live ratio.

Feature detection: checking…
Grid parameters — all values are typed CSS custom properties
180px
16px
100px
Auto-fill grid — card height computed by CSS typed arithmetic

How typed arithmetic works

Before typed multiplication/division (Chrome <138)
calc(300px - 100px) ✓ <length>
calc(300px / 100px) ✗ type error
calc(10px / 1px * 1deg) ✗ type error
workaround: tan(atan2(var(--a), 1px)) hack
With typed arithmetic (Chrome 138+)
@property --item-h { syntax: '<length>'; … }
calc(var(--item-h) - var(--gap-size)) ✓ <length>
calc(100cqw / var(--col-min-w)) ✓ <number>
calc(10px / 1px * 1deg) ✓ <angle>

Typed arithmetic chain

/* Register properties with explicit types */
@property --col-min-w {
  syntax: '<length>';
  inherits: true;
  initial-value: 180px;
}

@property --gap-size {
  syntax: '<length>';
  inherits: true;
  initial-value: 16px;
}

/* Typed subtraction: <length> - <length> → <length> */
.grid-item {
  height: calc(var(--item-h) - var(--gap-size));
  /* the controls are constrained to '<length>' values */
}

/* Typed division: <length> / <length> → <number> */
.grid-card-num {
  opacity: clamp(0.45, calc((100cqw / var(--col-min-w)) / 6), 1);
  /* cqw and --col-min-w cancel to a unitless ratio */
}

references

see also