CSS Ist Eine Stark Typisierte Sprache

Avatar of Eric Bailey
Eric Bailey am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Eine Möglichkeit, eine Programmiersprache zu klassifizieren, ist die Betrachtung, wie stark oder schwach typisiert sie ist. Hier bedeutet „typisiert“, ob Variablen zur Kompilierungszeit bekannt sind. Ein Beispiel hierfür wäre ein Szenario, in dem eine Ganzzahl (1) zu einem String hinzugefügt wird, der eine Ganzzahl enthält ("1").

result = 1 + "1";

Der String, der eine Ganzzahl enthält, könnte unbeabsichtigt aus einer komplizierten Logik mit vielen beweglichen Teilen generiert worden sein. Er könnte auch absichtlich aus einer einzigen Quelle der Wahrheit generiert worden sein.

Trotz der Konnotationen, die die Begriffe „schwach“ und „stark“ implizieren, ist eine stark typisierte Programmiersprache nicht unbedingt besser als eine schwach typisierte. Es kann Szenarien geben, in denen Flexibilität mehr benötigt wird als Starrheit und umgekehrt. Wie bei vielen Aspekten der Programmierung hängt die Antwort von mehreren externen Kontexten ab (d. h. „es kommt darauf an“).

Das andere Interessante ist, dass es keine formale Definition dafür gibt, was starke oder schwache Typisierung ausmacht. Das bedeutet, dass die Wahrnehmung, was als stark oder schwach typisierte Sprache gilt, von Person zu Person unterschiedlich ist und sich im Laufe der Zeit ändern kann.

TypeScript

JavaScript gilt als schwach typisierte Sprache, und diese Flexibilität trug zu seiner frühen Verbreitung im Web bei. Da sich das Web jedoch weiterentwickelt und industriellisiert hat, sind die Anwendungsfälle für JavaScript komplexer geworden.

Erweiterungen wie TypeScript wurden entwickelt, um dabei zu helfen. Betrachten Sie es als ein „Plugin“ für JavaScript, das dem Sprachumfang starke Typisierung hinzufügt. Dies hilft Programmierern, komplizierte Setups zu bewältigen. Ein Beispiel hierfür könnte eine datenintensive Single-Page-Anwendung für den E-Commerce sein.

TypeScript ist derzeit in der Webentwicklungsbranche sehr beliebt, und viele neue Projekte verwenden standardmäßig TypeScript, wenn sie mit der Einrichtung beginnen.

Kompilierungszeit

Kompilierungszeit ist der Moment, in dem eine Programmiersprache in Maschinencode umgewandelt wird. Sie ist ein Vorläufer der Laufzeit, dem Moment, in dem der Maschinencode vom Computer ausgeführt wird.

Wie bei vielen Dingen im Web ist die Kompilierungszeit etwas knifflig. Ein Setup, das TypeScript verwendet, fügt JavaScript-Code-Komponenten zusammen und kompiliert sie zu einer einzigen JavaScript-Datei, die der Browser lesen und ausführen kann.

Die Zeit, zu der die Komponenten kompiliert werden, ist, wenn sie alle zusammengefügt werden. TypeScript fungiert als eine Art Aufseher und wird Sie anmeckern, wenn Sie versuchen, die von Ihnen eingerichteten Typkonventionen vor dem Zusammenfügen zu brechen.

A tooltip that reads, “var content: any. Property ‘content’ does not exist on type ‘PropsWithChildren<Props>’. ts(2339). View Problem (Option F8). No quick fixes available. Tooltip is pointing towards an argument called “content.”
Ein Beispiel für einen TypeScript-Fehler in VS Code.

Die zusammengefügte JavaScript-Datei wird dann vom Browser übernommen, der seine eigene Kompilierungszeit hat. Die Kompilierungszeit des Browsers ist stark variabel und hängt davon ab

  • dem Gerät, auf dem sich der Browser befindet,
  • welche anderen Arbeiten der Browser gerade erledigt, und
  • welche anderen Arbeiten die anderen Programme des Geräts gerade erledigen.

TypeScript wird vom Browser nicht direkt verwendet, aber seine Präsenz ist spürbar. JavaScript ist fragil. TypeScript hilft bei dieser Fragilität, indem es versucht, Fehler im Code-Editor im Vorfeld zu verhindern. Dies verringert die Wahrscheinlichkeit, dass Fehler in dem von den Browsern gelesenen JavaScript auftreten – Fehler, die dazu führen würden, dass JavaScript auf der Website oder Webanwendung, die eine Person nutzt, nicht mehr funktioniert.

CSS

CSS ist eine deklarative, domänenspezifische Programmiersprache. Sie ist auch stark typisiert. Zum größten Teil bleiben Werte in CSS so deklariert, wie sie geschrieben wurden. Wenn ein Wert ungültig ist, verwirft der Browser die gesamte Eigenschaft.

Typen in CSS

Die Liste der Typen in CSS ist umfassend. Sie sind

Textuelle Typen
  • Global definierte Schlüsselwörter
    • initial
    • inherit
    • unset
    • revert
  • Benutzerdefinierte Identifikatoren, die speziell für Dinge verwendet werden, wie z. B. die Angabe eines Namens für die grid-area
  • Strings, wie z. B. "hallo"
  • URLs, wie z. B. https://css-tricks.de/
  • Mit Bindestrichen versehene Identifikatoren (--), die zur Erstellung benutzerdefinierter Eigenschaften verwendet werden (mehr dazu gleich)
Numerische Typen
  • Ganzzahlen, bei denen es sich um Dezimalzahlen von 0–9 handelt
  • Reelle Zahlen, wie z. B. 3.14
  • Prozentangaben, wie z. B. 25%
  • Dimensionen, eine Zahl mit angehängter Einheit, wie z. B. (100px oder 3s)
  • Verhältnisse, wie z. B. 16/9
  • flex, eine variable Länge für die Berechnung von CSS-Grids
Mengentypen
  • Längen
  • Winkel, wie z. B. 15deg
  • Zeit, wie z. B. 250ms
  • Frequenzen, wie z. B. 16Hz
  • Auflösung, wie z. B. 96dpi

Dimensionen und Längen mögen ähnlich erscheinen, aber Dimensionen können Prozente enthalten, Längen jedoch nicht.

Farbtypen
  • Schlüsselwörter
    • Benannte Farben, wie z. B. papayawhip
    • transparent
    • currentColor
  • RGB-Farben
    • Hexadezimale Notation, wie z. B. #FF8764
    • RGB/RGBa-Notation, wie z. B. rgba(105, 221, 174, 0.5)
  • HSL/HSLA-Farben, wie z. B. hsl(287, 76%, 50%)
  • Systemfarben, wie z. B. ButtonText
Bildtypen
  • Image, was eine URL-Referenz zu einer Bilddatei oder einem Gradienten ist
  • color-stop-list, eine Liste von zwei oder mehr Farbstopps, die für die Gradientennote verwendet wird
  • linear-color-stop, ein Farb- und Längen-Ausdruck, der zur Angabe eines Gradienten-Farbstopps dient
  • linear-color-hint, eine Längenprozentangabe zur Interpolation von Farben
  • ending-shape, das ein Schlüsselwort entweder circle oder ellipse für radiale Gradienten verwendet
2D-Positionierungstypen
  • Schlüsselwörter
    • top
    • right
    • bottom
    • left
    • center
  • Eine prozentuale Länge, wie z. B. 25%

Programmierung in CSS

Der Großteil der Programmierung in CSS besteht aus dem Schreiben von Selektoren, gefolgt von der Angabe einer Reihe von Eigenschaften und ihren erforderlichen Werten. Sammlungen von Selektoren verleihen Inhalten eine visuelle Form, ähnlich wie Sammlungen von JavaScript-Logik Features erstellen.

CSS hat Funktionen. Es kann Berechnungen, bedingte Logik, algorithmische Ausdrücke, Zustände und modulbasiertes Verhalten ausführen. Es verfügt auch über benutzerdefinierte Eigenschaften, die effektiv CSS-Variablen sind und es ermöglichen, Werte dynamisch zu aktualisieren. Man kann sogar FizzBuzz mit CSS lösen.

Wie andere Programmiersprachen gibt es auch eine „Meta“-Schicht mit unterschiedlichen Gedanken und Techniken, wie man Dinge organisieren, verwalten und pflegen kann.

Fehler werfen

Im Gegensatz zu anderen Programmiersprachen, bei denen der Code weitgehend im Verborgenen existiert, ist CSS hochgradig visuell. Sie sehen keine Warnungen oder Fehler in der Konsole, wenn Sie einen ungültigen Wert für eine Eigenschaftsdeklaration verwenden, aber Sie erhalten visuelle Darstellungen, die sich nicht wie erwartet aktualisieren.

Der Grund dafür ist, dass CSS resilient ist. Wenn die visuellen Darstellungen aufgrund einer falsch konstruierten Deklaration nicht aktualisiert werden, priorisiert CSS: die Anzeige von Inhalten um jeden Preis sicherstellen und alle anderen gültigen Deklarationen rendern, die es möglicherweise kann. Dies steht im Einklang mit den Designprinzipien der Sprache, den Prinzipien der Plattform und den übergeordneten Zielen der Mission des Webs.

Beweis

Lassen Sie uns anhand von drei Beispielen demonstrieren, wie die starke Typisierung in CSS die Leitplanken aufrechterhält: eines mit einer geradlinigen Eigenschaften-/Wertdeklaration, eines mit Berechnung und eines mit der Neudefinition einer benutzerdefinierten Eigenschaft.

Beispiel 1: Einfache Eigenschaften-/Wertdeklaration

Siehe den Pen Basic example von Eric Bailey (@ericwbailey) auf CodePen.

Für dieses Beispiel versteht der Browser die Deklaration „potato“ für border-style des Banners nicht. Beachten Sie, dass die anderen Eigenschaften-/Wertdeklarationen der .banner-Klassenauswahl vom Browser honoriert und gerendert werden, obwohl border-style einen Typenfehler aufweist. Dies ist ein Beispiel dafür, wie resilient CSS ist.

Die Deklaration border-style erwartet einen der folgenden Textuellen Styl-Typen

  • Global definierte Schlüsselwörter oder ein
  • Mit Bindestrichen versehener Identifikator für eine benutzerdefinierte Eigenschaft.

Wenn wir border-style auf einen gültigen, typisierten Wert wie dotted aktualisieren, rendert der Browser den Rand!

Beispiel 2: Berechnung

Die Funktion calc() in CSS erlaubt es uns, zwei Argumente und einen Operator zu nehmen, um ein berechnetes Ergebnis zu liefern. Wenn eines der Argumente keinen gültigen Typ verwendet, funktioniert die Berechnung nicht.

In diesem Pen erwartet die Eigenschaft font-size der p-Selektor einen Wert mit einem numerischen Dimensionstyp (z. B. 1.5rem). Die Berechnungsfunktion liefert jedoch einen ungültigen Typwert für die font-size-Eigenschaft. Das liegt daran, dass das zweite Argument der calc()-Funktion ein String ("2rem") und kein numerischer Dimensionstyp ist.

Aus diesem Grund fällt die Schriftgröße des Absatzes auf den nächstbesten anwendbaren übergeordneten Knoten zurück – die font-size von 1.5rem, die auf dem body-Element deklariert ist.

Das ist etwas ins Detail gehend, aber es lohnt sich, darauf hinzuweisen: Die Kombination zweier benutzerdefinierter Eigenschaften in einer calc()-Funktion kann Fehler verursachen. Während beide benutzerdefinierten Eigenschaften für sich allein gültig sein mögen, akzeptiert calc() keine Textuellen Typen, die mit Bindestrichen versehen sind. Denken Sie an ein Szenario, in dem wir versuchen, benutzerdefinierte Eigenschaften zu multiplizieren, die nicht übereinstimmende Einheiten enthalten, z. B. --big: 500px und --small: 1em.

Beispiel 3: Neudefinierte benutzerdefinierte Eigenschaft

Ähnlich wie JavaScript-Variablen können Werte benutzerdefinierter Eigenschaften neu definiert werden. Diese Flexibilität ermöglicht es beispielsweise, einfach dunkle Farbschemata für den Dark Mode zu erstellen.

Im :root-Selektor dieses CodePens habe ich eine benutzerdefinierte Eigenschaft --color-cyan mit dem Wert #953FE3 gesetzt. Dann habe ich in der .square-Klasse den Wert der benutzerdefinierten Eigenschaft --color-cyan auf top geändert. Obwohl top ein gültiger, typisierter Wert ist, ist es kein Typ, den background-color akzeptiert.

Beachten Sie, dass die aktualisierte benutzerdefinierte Eigenschaft auf .square beschränkt ist und andere Verwendungen nicht beeinflusst, wie z. B. den rechten Rand des Satzes „Don’t play to type“. Und wenn Sie die neu definierte benutzerdefinierte Eigenschaft aus .square entfernen, sehen Sie, wie die cyanfarbene Hintergrundfarbe zurückkehrt.

Auch wenn dies etwas konstruiert ist, dient es als Beispiel dafür, wie die Neudefinition von benutzerdefinierten Eigenschaften aus dem Ruder laufen kann, wenn man nicht vorsichtig ist.

Dieses Phänomen tritt in Projekten mit schlechter Kommunikation, größeren CSS-Codebasen und Situationen auf, in denen CSS-Präprozessoren verwendet werden, um benutzerdefinierte Eigenschaften in großem Maßstab zu erstellen.

Werkzeuge

Mit dem Wissen der Nachbetrachtung glaube ich, dass das Fehlen von Konsolenwarnungen für CSS ein Mangel ist und zu vielen negativen Wahrnehmungen der Sprache beigetragen hat.

Zu hoffen, dass ein Entwickler eine potenziell winzige visuelle Änderung bemerkt, ist zu viel verlangt und trifft ihn nicht dort, wo er sich mit den meisten seiner anderen täglichen Werkzeuge befindet. Es gibt ein paar Initiativen, von denen ich weiß, dass sie versuchen, dies anzugehen.

Erstens ist da stylelint, ein Linter, der speziell für CSS und CSS-ähnliche Präprozessorsprachen entwickelt wurde. Stylelint kann mit Code-Editoren, Task-Runnern, Kommandozeilentools und GitHub Actions integriert werden, um Ihr CSS unter Kontrolle zu halten. Dies ermöglicht es, Entwickler dort abzuholen, wo sie bereits sind.

A tooltip that reads, “var content: any. Property ‘content’ does not exist on type ‘PropsWithChildren<Props>’. ts(2339). View Problem (Option F8). No quick fixes available. Tooltip is pointing towards an argument called “content.”
stylelint Terminalausgabe.

Zweitens gibt es die ausgezeichnete Sammlung von CSS-Inspektionsoptionen in den Entwicklertools von Firefox. Insbesondere möchte ich auf die Möglichkeit hinweisen, ungenutztes CSS zu identifizieren. Dies ist äußerst hilfreich bei der Identifizierung von Selektoren, die möglicherweise mit einem Typenfehler in Konflikt geraten sind.

Tooltip attached to an unused selector in the Developer panel. The tooltip reads, “vertical-align has no effect on this element since it’s not an inline or table-cell element. Try adding display: inline or display: table-cell. Learn more. Screenshot.”
Firefox Developer Edition

Zusammenfassung

CSS ist seit seiner Entstehung als Programmiersprache stark typisiert, und als Programmiersprache existiert sie schon sehr lange. Außerdem hat sie in letzter Zeit viel dazugelernt. Wenn Sie sich nicht informiert haben, gibt es einige neue, erstaunliche Funktionen.

Da stark typisiertes JavaScript immer beliebter wird, hoffe ich, dass es Entwicklern hilft, sich mit dem festen, aber flexiblen Ansatz von CSS vertrauter zu machen.


Vielen Dank an Miriam Suzanne für ihr Feedback.