angular/components · error

mat-grid-list: invalid ratio given for row-height: "${value}

Error message

mat-grid-list: invalid ratio given for row-height: "${value}"

What it means

When rowHeight is given as a ratio string (e.g. '1:1' or '4:3'), RatioRowStyler._parseRatio splits on ':' and requires exactly two parts. Any string with a different number of ':'-separated segments throws this error.

Source

Thrown at src/material/grid-list/tile-styler.ts:260

      'paddingBottom',
      calc(`${this.getTileSpan(this.baseTileHeight)} + ${this.getGutterSpan()}`),
    ];
  }

  reset(list: TileStyleTarget) {
    list._setListStyle(['paddingBottom', null]);

    list._tiles.forEach(tile => {
      tile._setStyle('marginTop', null);
      tile._setStyle('paddingTop', null);
    });
  }

  private _parseRatio(value: string): void {
    const ratioParts = value.split(':');

    if (ratioParts.length !== 2 && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw Error(`mat-grid-list: invalid ratio given for row-height: "${value}"`);
    }

    this.rowHeightRatio = parseFloat(ratioParts[0]) / parseFloat(ratioParts[1]);
  }
}

/**
 * This type of styler is instantiated when the user selects a "fit" row height mode.
 * In other words, the row height will reflect the total height of the container divided
 * by the number of rows.  Example `<mat-grid-list cols="3" rowHeight="fit">`
 *
 * @docs-private
 */
export class FitTileStyler extends TileStyler {
  setRowStyles(tile: MatGridTile, rowIndex: number): void {
    // Percent of the available vertical space that one row takes up.
    let percentHeightPerTile = 100 / this._rowspan;

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Provide exactly two segments separated by one colon: rowHeight="1:1" or "4:3".
  2. If a fixed height was intended, pass a number or CSS unit instead (rowHeight="100px").
  3. Validate dynamic ratio strings before binding: /^\d+(\.\d+)?:\d+(\.\d+)?$/.test(v).
  4. Check binding interpolation for stray colons from template expressions.

Example fix

// before
<mat-grid-list cols="3" rowHeight="1">
// after
<mat-grid-list cols="3" rowHeight="1:1"></mat-grid-list>
Defensive patterns

Strategy: validation

Validate before calling

function isRatioRowHeight(v: string): boolean {
  return v.split(':').length === 2 && v.split(':').every(p => p.trim() !== '' && !isNaN(Number(p)));
}

Type guard

function isRatioString(v: unknown): v is `${number}:${number}` {
  return typeof v === 'string' && /^\d+(\.\d+)?:\d+(\.\d+)?$/.test(v);
}

Prevention

When it happens

Trigger: Passing rowHeight="1" (no colon, intended as ratio), rowHeight="1:1:1" (extra segment), or rowHeight="" with the ratio styler selected — anything whose split(':') length !== 2.

Common situations: Confusing the fixed-height and ratio syntax (forgetting the colon); dynamically building the ratio string and appending an extra part; empty bindings that should have been numbers.

Related errors


AI-assisted analysis of angular/components@0411926e7d (2026-08-31). Data as JSON: /api/errors/3692b0ec8a112b97. Report an issue: GitHub.