Signatur
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
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
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);
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);
}
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());
// 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 überelement.styleund Zeichenketten bereit. - Abstrakt:
new CSSMathValue()löst einenTypeErroraus. Erzeuge stattdessen immer eine Unterklasse. - Vereinfachung: Rechenmethoden wie
add()odermul()fassen verträgliche Einheiten sofort zu einemCSSUnitValuezusammen. Ob ein Ergebnis einCSSMathValueist, hängt also von den Einheiten ab. Prüfe den Typ, bevor du auf.valueoder.valueszugreifst. - Subtraktion und Division werden intern als
CSSMathSummitCSSMathNegatebzw. alsCSSMathProductmitCSSMathInvertdargestellt. Es gibt keine eigenen Operatoren"sub"oder"div". CSSMathClampwird nicht überall unterstützt. Prüfe die Unterklasse vor der Nutzung einzeln mittypeof CSSMathClamp !== 'undefined'.- Bei
computedStyleMap()lösen Browser berechnete Werte oft schon zu absoluten Werten auf.CSSMathValue-Objekte bekommt man deshalb vor allem überattributeStyleMapoder beim Auslesen von Stylesheet-Regeln (CSSStyleRule.styleMap).