Start · Sprachen · JavaScript · Referenz · CSSMathValue

CSSMathValue

Schnittstelle

Abstraktes Basisinterface des CSS Typed OM für berechnete numerische Werte aus <code>calc()</code>, <code>min()</code>, <code>max()</code> und <code>clamp()</code>.

seit JavaScript Chrome/Edge 66+, Safari 16.4+; Firefox: nicht unte Kategorie: webapi

Signatur

interface CSSMathValue extends CSSNumericValue

Beschreibung

CSSMathValue gehört zum CSS Typed Object Model (Houdini). Es beschreibt numerische CSS-Werte, die sich nicht auf eine einzelne Zahl mit Einheit zurückführen lassen, zum Beispiel calc(100% - 20px) oder max(50vw, 300px). Solche Werte stellt das Typed OM nicht als Zeichenkette dar, sondern als Baum aus Objekten, den man auswerten und verändern kann.

Das Interface ist abstrakt: Man erzeugt nie direkt ein CSSMathValue, sondern immer eine der Unterklassen:

  • CSSMathSum: Summe (operator = "sum")
  • CSSMathProduct: Produkt ("product")
  • CSSMathNegate: Negation, also Subtraktion innerhalb einer Summe ("negate")
  • CSSMathInvert: Kehrwert, also Division innerhalb eines Produkts ("invert")
  • CSSMathMin / CSSMathMax: min() / max() ("min" / "max")
  • CSSMathClamp: clamp() ("clamp")

Die einzige eigene Eigenschaft ist die schreibgeschützte Eigenschaft operator. Sie gibt an, welche Rechenart das Objekt darstellt. Alle anderen Methoden erbt CSSMathValue von CSSNumericValue, darunter add(), sub(), mul(), div(), min(), max(), equals(), to(), toSum() und type().

In der Praxis bekommt man CSSMathValue-Objekte auf zwei Wegen: Man liest Werte über element.attributeStyleMap bzw. computedStyleMap() aus, oder man kombiniert Werte mit unterschiedlichen Einheiten, etwa CSS.px(10).add(CSS.percent(50)). Mit instanceof CSSMathValue lässt sich prüfen, ob ein Wert berechnet ist oder schon als einfacher CSSUnitValue vorliegt.

Rückgabewert

Typ
CSSMathValue
Beschreibung
Nicht direkt konstruierbar. Instanzen sind immer Objekte einer Unterklasse wie CSSMathSum oder CSSMathMax. Die Eigenschaft operator liefert einen string: "sum", "product", "negate", "invert", "min", "max" oder "clamp".

Beispiele

Werte mit unterschiedlichen Einheiten verrechnen

// px und % lassen sich nicht zusammenfassen, deshalb entsteht ein CSSMathSum
const breite = CSS.percent(100).sub(CSS.px(20));

console.log(breite instanceof CSSMathValue); // true
console.log(breite.constructor.name);        // Name der Unterklasse
console.log(breite.operator);                // Rechenart
console.log(breite.toString());              // als CSS-Text
true CSSMathSum sum calc(100% - 20px)

Unterklassen direkt erzeugen und als Stil setzen

const box = document.querySelector('.box');

// entspricht max(50vw, 300px)
const mindestBreite = new CSSMathMax(CSS.vw(50), CSS.px(300));
console.log(mindestBreite.operator);   // "max"
console.log(mindestBreite.toString()); // "max(50vw, 300px)"

box.attributeStyleMap.set('width', mindestBreite);
console.log(box.style.width);
max max(50vw, 300px) max(50vw, 300px)

Berechnete Inline-Werte auslesen und zerlegen

const el = document.createElement('div');
el.style.width = 'calc(100% - 2em)';

const wert = el.attributeStyleMap.get('width');

if (wert instanceof CSSMathValue) {
  console.log(`Operator: ${wert.operator}`);
  // CSSMathSum besitzt eine Liste values (CSSNumericArray)
  for (const teil of wert.values) {
    console.log(teil.constructor.name, teil.toString());
  }
} else {
  console.log('Einfacher Wert:', wert.value, wert.unit);
}
Operator: sum CSSUnitValue 100% CSSMathNegate -2em

Automatische Vereinfachung erkennen

// Gleiche Einheiten werden sofort zusammengefasst, es entsteht kein CSSMathValue
const a = CSS.px(10).add(CSS.px(5));
console.log(a instanceof CSSMathValue, a.toString());

// Unterschiedliche Einheiten bleiben ein berechneter Wert
const b = CSS.px(10).mul(CSS.number(2)).add(CSS.em(1));
console.log(b instanceof CSSMathValue, b.toString());
false 15px true calc(20px + 1em)

// Wichtig · Fallstricke

  • Browser-Unterstützung: Das CSS Typed OM gibt es in Chromium-Browsern (ab Version 66) und in Safari (ab 16.4). Firefox unterstützt es bislang nicht. Prüfe die Verfügbarkeit mit if ('CSSMathValue' in window) und halte eine Ersatzlösung über element.style und Zeichenketten bereit.
  • Abstrakt: new CSSMathValue() löst einen TypeError aus. Erzeuge stattdessen immer eine Unterklasse.
  • Vereinfachung: Rechenmethoden wie add() oder mul() fassen verträgliche Einheiten sofort zu einem CSSUnitValue zusammen. Ob ein Ergebnis ein CSSMathValue ist, hängt also von den Einheiten ab. Prüfe den Typ, bevor du auf .value oder .values zugreifst.
  • Subtraktion und Division werden intern als CSSMathSum mit CSSMathNegate bzw. als CSSMathProduct mit CSSMathInvert dargestellt. Es gibt keine eigenen Operatoren "sub" oder "div".
  • CSSMathClamp wird nicht überall unterstützt. Prüfe die Unterklasse vor der Nutzung einzeln mit typeof CSSMathClamp !== 'undefined'.
  • Bei computedStyleMap() lösen Browser berechnete Werte oft schon zu absoluten Werten auf. CSSMathValue-Objekte bekommt man deshalb vor allem über attributeStyleMap oder beim Auslesen von Stylesheet-Regeln (CSSStyleRule.styleMap).