Ich helfe beim Schreiben technischer Dokumentationen und eine Funktion, über die ich dieses Jahr geschrieben habe, die wirklich herausragt, ist das Typed Object Model (oder Typed OM). Wenn Sie es noch nicht kennen, würden Sie es verstehen, da es ziemlich neu ist. Es gehört zur CSS Houdini Suite von APIs und scheint oberflächlich betrachtet am wenigsten aufregend. Es ist jedoch die Grundlage für sie alle und wird letztendlich verändern, wie wir CSS als Sprache betrachten.
Es ermöglicht das Typisieren von Werten in CSS. Erinnern Sie sich an die Basissyntax von CSS
selector {
property: value;
}
Dieser Wert kann vieles sein: Farben, Einheiten, Bilder, Wörter. Was für CSS Sinn ergibt, aber für uns, wenn wir darauf zugreifen und ihn auf irgendeine Weise ändern wollen, kommt er als String.
Typed OM erlaubt, dass dieser stattdessen als Typ zurückgegeben wird. Wenn wir zum Beispiel 10px in JavaScript abrufen würden, anstatt '10px' zurückzugeben, erhalten wir die Zahl 10 und die Einheit 'px'. Was die Arbeit damit erheblich erleichtert.
Sie haben vielleicht einige der erstaunlichen Demos von Ana Tudor gesehen. In ihrem Beispiel „Hollow“ registriert sie benutzerdefinierte Eigenschaften in JavaScript, um sie in ihrem CSS zu verwenden. Sie verwendet die Properties & Values API und kann somit die Typen dieser Eigenschaften bestimmen. Dies wäre nicht möglich, wenn Typed OM nicht existieren würde.
Wie wäre es mit einem Beispiel
Auf den ersten Blick scheint es etwas mehr Arbeit zu sein als die Art und Weise, wie wir es gewohnt sind, Stile abzurufen und festzulegen, aber es gibt viele Vorteile. Wenn wir zum Beispiel die Breite eines Elements abrufen wollen, würden wir Folgendes tun:
const elementWidth = getComputedStyle(myElement).width;
// returns '300px'
Wir greifen hier nicht nur auf einen String zu, sondern getComputedStyle erzwingt ein erneutes Layout. Wir sind uns möglicherweise nicht bewusst, welche Einheiten verwendet werden, und daher wird der numerische Teil des Strings schwierig abzurufen, und wenn wir dies mehrmals in unserem Code ausführen, könnte dies die Leistung beeinträchtigen.
Wenn wir Typed OM verwenden und einen typisierten Wert zurückgeben möchten, müssten wir über computedStyleMap() und dessen get()-Methode auf die Eigenschaften und Werte zugreifen.
const elementWidth = myElement.computedStyleMap().get('width');
// returns CSSUnitValue {value: 300, type: 'px'}
Jetzt können wir den Wert und die Einheit getrennt abrufen, und der Wert wird hier als Ganzzahl zurückgegeben.
elementWidth.value // 300
elementWidth.unit // 'px'
Wir haben auch kein erneutes Layout erzwungen, was nichts weniger als ein Gewinn ist. Ich wette, Sie fragen sich jetzt und ja, Sie können nicht nur auf den CSS-Wert als Typ zugreifen, sondern auch ganz einfach Einheitswerte erstellen, über das globale CSS-Objekt.
let newWidth = CSS.px(320);
// returns CSSUnitValue {value: 320, type: 'px'}
Das ist ein kleines Beispiel, das leicht zu zeigen ist, da der Einheitenteil der Spezifikation erheblich für einige andere Wertetypen ausgearbeitet wurde. Aber unabhängig davon ermöglicht es viel weniger String-Vergleiche und mehr Flexibilität.
Eine weitere gut spezifizierte Wertengruppe sind Transformationswerte: translate, rotate, scale usw. Das ist großartig, denn wenn wir einen dieser Werte auf einem Element ohne Typed OM ändern wollten, kann das schwierig sein, besonders wenn wir mehr als einen gesetzt haben.
.myElement {
transform: rotate(10deg) scale(1.2);
}
Nehmen wir an, wir möchten die Rotation erhöhen. Wenn wir diese Eigenschaft mit getComputedStyle() abrufen, wird eine Matrix zurückgegeben.
const transform = getComputedStyle(myElement).transform;
// returns matrix(0.984808, 0.173648, -0.173648, 0.984808, 0, 0)
Bei den Transformationen, die wir auf dem Element haben, können wir nicht einen Wert aus der Matrix extrahieren. Ich werde hier nicht über Vektoren, Skalarwerte und Skalarprodukte sprechen, aber es genügt zu sagen, dass Sie keinen einzelnen Wert extrahieren können, sobald die Matrix gebildet wurde. Es wird definitiv zahlreiche Abbildungen geben.
Wenn Sie nur eine Transformation oder Skalierung haben, ist dies durch Abgleich von Strings möglich, wo sich der Wert in der Matrix befindet. Aber das ist Stoff für einen anderen Tag.
Wir könnten benutzerdefinierte Eigenschaften verwenden, um den Wert dieser Transformationen festzulegen und diese zu aktualisieren.
.myElement {
--rotate: 10deg;
transform: rotate(var(--rotate)) scale(1.2);
}
myElement.style.setProperty('--rotate', '15deg');
Wir müssen jedoch den Namen der benutzerdefinierten Eigenschaft kennen und übergeben immer noch einen String.
Hier kommt Typed OM ins Spiel. Werfen wir einen Blick darauf, was von computedStyleMap zurückgegeben wird.
myElement.computedStyleMap().get('transform');
/* returns
CSSTransformValue {
0: CSSRotate {...}
1: CSSScale {...}
} */
Jeder Transformationswert hat seinen eigenen Typ. Es gibt CSSRotate und CSSScale für den obigen Code. Sowie alle anderen wie Skew und Translate. Anstatt also mit Matrizen umzugehen oder immer noch mit Strings zu arbeiten, können wir diese Typen erstellen und eine CSSTransformValue damit anwenden.
const newTransform = new CSSTransformValue([
new CSSRotate(CSS.deg(15)),
new CSSScale(CSS.number(1.2), CSS.number(1.2))
])
myElement.attributeStyleMap.set('transform', newTransform);
Beachten Sie, wie wir die Transformationstypen mit der Klassenmethode und dem new-Schlüsselwort erstellen, anstatt mit der Factory-Methode für numerische Werte.
Wir haben viel mehr Kontrolle über jeden einzelnen Wert, was sehr nützlich ist, wenn wir mehrere Werte in CSS deklarieren.
Ich habe einen Pen mit all diesem Beispielcode hier zusammengestellt.
Es ist das Fundament
Wenn wir mit anderen APIs der Houdini-Suite vertrauter werden, werden die Vorteile all dessen noch offensichtlicher. Wenn wir mit der Properties and Values API eine neue benutzerdefinierte Eigenschaft deklarieren, legen wir einen Typ fest und erhalten automatisch Fehlerbehandlung. Diese Wertetypen werden auch an die Worklets der Paint API und Layout API übergeben, sodass wir auch dort die Leistung nutzen können.
Es gibt weitere Typen, die ich nicht erwähnt habe, weitere Typen werden kommen und wirklich viel mehr darüber zu schreiben. Wenn nicht bereits geschehen, wird Typed OM derzeit in allen wichtigen Browsern implementiert. Es hat dieses Jahr definitiv mein Interesse geweckt, also halten Sie Ausschau danach, wenn 2020 kommt!
Danke für die klaren Beispiele, sie helfen wirklich, das Potenzial dieser neuen API zu sehen – definitiv nützlich. Prost!