Signatur
Beschreibung
CSSNumericArray gehört zum CSS Typed Object Model (Houdini) und ist eine array-ähnliche Liste von CSSNumericValue-Objekten. Man erzeugt sie nie direkt, sondern erhält sie über die Eigenschaft values der mathematischen Ausdrucksklassen CSSMathSum, CSSMathProduct, CSSMathMin und CSSMathMax, also etwa aus einem geparsten calc()-, min()- oder max()-Ausdruck.
length gibt die Anzahl der Operanden auf der obersten Ebene dieses Ausdrucks als ganze Zahl zurück. Damit kann man die Liste per Index-Zugriff (values[i]) in einer klassischen for-Schleife durchlaufen, prüfen, ob ein Ausdruck überhaupt mehrere Terme hat, oder Grenzen für den Zugriff festlegen.
Verschachtelte Ausdrücke zählen jeweils nur als ein Element: Bei calc(10px + 2 * 3em) enthält die Summe zwei Elemente – einen CSSUnitValue und ein CSSMathProduct. Um alle Blätter eines Ausdrucksbaums zu zählen, muss man ihn rekursiv durchlaufen.
Rückgabewert
CSSNumericValue-Einträge im Array.Beispiele
Anzahl der Operanden einer CSSMathSum
// Summe aus drei Werten mit unterschiedlichen Einheiten
const sum = new CSSMathSum(CSS.px(10), CSS.percent(50), CSS.em(2));
console.log(sum.values instanceof CSSNumericArray);
console.log(sum.values.length);
calc()-Ausdruck aus dem Inline-Style auswerten
const box = document.querySelector('.box');
box.attributeStyleMap.set('width', 'calc(100% - 20px)');
const width = box.attributeStyleMap.get('width');
if (width instanceof CSSMathSum) {
const { values } = width;
console.log(`calc() mit ${values.length} Termen`);
for (let i = 0; i < values.length; i++) {
console.log(i, values[i].constructor.name);
}
}
Verschachtelte Ausdrücke: oberste Ebene vs. alle Blätter
const expr = CSSNumericValue.parse('calc(10px + 2 * 3em)');
// Nur die oberste Ebene
console.log(expr.values.length);
// Alle Blattwerte rekursiv zählen
const countLeaves = (value) => {
if ('values' in value) {
return Array.from(value.values).reduce((n, v) => n + countLeaves(v), 0);
}
if ('value' in value && value instanceof CSSMathNegate) {
return countLeaves(value.value);
}
return 1;
};
console.log(countLeaves(expr));
Operanden von max() prüfen
const clamped = new CSSMathMax(CSS.px(320), CSS.vw(50), CSS.rem(20));
const { length } = clamped.values;
console.log(length > 1 ? `max() mit ${length} Kandidaten` : 'nur ein Wert');
// Wichtig · Fallstricke
- Schreibgeschützt:
lengthist nur ein Getter. Im nicht-strikten Modus wird eine Zuweisung stillschweigend ignoriert, im Strict Mode (z. B. in ES-Modulen) wirft sie einenTypeError. Auch das Array selbst ist unveränderlich – es gibt keinpush()odersplice(). - Kein echtes Array:
CSSNumericArrayist iterierbar und hatforEach(),entries(),keys()undvalues(), aber keinmap(),filter()oderreduce(). MitArray.from()oder dem Spread-Operator ([...arr]) wandelt man es in ein echtes Array um. - Subtraktion und Division: Aus
a - bwird in der Summe einCSSMathNegate, ausa / bim Produkt einCSSMathInvert. Diese zählen als eigenes Element, ihre inneren Werte aber nicht zusätzlich. - Vereinfachung: Der Browser kann Ausdrücke beim Parsen vereinfachen (z. B.
calc(1px + 2px)zu3px). Dann entsteht gar keinCSSMathSumund damit auch keinevalues. Vor dem Zugriff also immer den Typ prüfen, etwa mitinstanceof CSSMathSumoder'values' in wert. - Kompatibilität: CSS Typed OM wird von Chromium-Browsern (ab Version 66) und Safari (ab 16.4) unterstützt, von Firefox aber nicht. Per Feature-Erkennung absichern:
if ('CSSNumericArray' in window) { … }.