12k
All articles

Ein Stylesheet mit Project Wallace auditieren

Ein CSS-Audit mit Project Wallace macht einzigartige Farben, Schriftgrößen, Spezifität, Duplikate und Dateigröße zu konkreten Korrekturen.

OpenReplay Team
OpenReplay Team
Ein Stylesheet mit Project Wallace auditieren

Ein CSS-Audit mit Project Wallace bedeutet, ein Stylesheet in den Online-Analyzer einzufügen und fünf Zahlen zu lesen: eindeutige Farben, eindeutige Font-Sizes, maximale Selektor-Spezifität (mit den Zählwerten für ids und !important daneben), die Differenz zwischen Gesamtzahl und eindeutiger Anzahl der Deklarationen sowie unkomprimierte Dateigröße gegenüber Gzip-Dateigröße. Jede dieser Zahlen verweist auf eine andere Maßnahme.

Wenn Ihr Stylesheet drei Jahre alt ist, ahnen Sie vermutlich bereits, dass es abgedriftet ist. Was Ihnen fehlt, ist eine Zahl, die Sie in ein Ticket schreiben können. „Das CSS wirkt unaufgeräumt” wird nicht priorisiert; „wir liefern sechs Grautöne aus, obwohl das Design zwei definiert” schon.

Dieser Artikel schickt ein kleines Fixture-Stylesheet durch den Analyzer, liest die Ausgabe Metrik für Metrik und ordnet jedem Befund die konkrete Änderung zu, die er auslösen sollte. Es geht um die Diagnose. Der Folgeartikel How to Organize CSS in Modern Web Projects behandelt die Behandlung.

Die wichtigsten Erkenntnisse

  • Browser verwerfen CSS, das sie nicht parsen oder nicht erkennen können, und rendern weiter – deshalb sammelt ein Stylesheet Fehler an, ohne dass jemals ein Build fehlschlägt.
  • Wenn Sie CSS einfügen oder hochladen, führt Project Wallace die Analyse in einem WebWorker auf Ihrem eigenen Gerät aus, das Stylesheet verlässt den Browser also nie.
  • Die Differenz zwischen ausgelieferten eindeutigen Farben und der im Design definierten Palette ist die messbare Form von Design-Drift, und die Lösung besteht darin, Werte in Tokens zusammenzuführen – nicht darin, Regeln zu löschen.
  • Ein Spezifitäts-Ausschlag mitten im Stylesheet kostet mehr als ein hohes Maximum am Ende, denn jedes spätere Override muss sich auf dieselbe Höhe hocharbeiten.
  • Leere Regeln sind die eine Audit-Korrektur, die nie eine visuelle Regressionsprüfung braucht; doppelte Deklarationen erfordern vor dem Entfernen eine Einschätzung.

Warum findet ein CSS-Audit, was der Build nicht finden kann?

Ein Browser, der auf eine CSS-Deklaration trifft, die er nicht parsen oder nicht erkennen kann, verwirft diese Deklaration und rendert die Seite weiter. Genau deshalb kann ein Stylesheet über Jahre Fehler ansammeln, ohne dass ein einziger Build fehlschlägt. Dieses Wiederaufsetzen ist spezifiziertes Verhalten. Nach den Error-Handling-Regeln im CSS Syntax Module Level 3 wird die halb aufgebaute Deklaration verworfen, der Parser springt über das nächste Semikolon hinweg, und das normale Parsen setzt dort fort.

Die Folge: CSS-Schäden sehen nie wie ein Fehlschlag aus. Sie sehen aus wie Drift: ein vierter Grauton, der zwei Punkte vom dritten abweicht, eine 17px-Überschrift zwischen den Stufen 16px und 18px, ein unter Deadline-Druck hinzugefügter id-Selektor und danach ein !important, um ihn zu übertrumpfen. Nichts davon geht kaputt. Alles davon macht die nächste Änderung schwieriger.

Wie führt man den Project-Wallace-Analyzer aus?

Der Project Wallace CSS Analyzer nimmt Eingaben auf drei Wegen entgegen: als Website-URL, als hochgeladene Datei oder als direkt eingefügtes CSS. Beim Einfügen oder Hochladen von CSS passiert die Arbeit lokal: Ein WebWorker auf Ihrem eigenen Gerät übernimmt die Analyse, und nichts von dem, was Sie einfügen, wird irgendwohin gesendet. Dieses Design stammt aus dem Analyzer-Rewrite von 2021. Der URL-Modus ruft die Zielseite notwendigerweise vor der Analyse über das Netzwerk ab.

Die Eingabeseite besitzt einen „Prettify CSS?”-Schalter, mit einem Hinweis daneben, dass diese Option die Zahlen leicht verschiebt. Legen Sie einen Zustand fest und behalten Sie ihn für alle Durchläufe bei, die Sie miteinander vergleichen wollen.

Hier ist das Fixture. Drei Beitragende, zwei Jahre, eine Header- und eine Card-Komponente:

/* header.css — three contributors, two years */
#site-header {
  background: #f5f5f5;
  color: #333333;
  font-size: 16px;
}

#site-header .nav-link {
  color: #343434;
  font-size: 15px;
  padding: 8px 12px;
}

.nav-link:hover {
  color: #222222 !important;
}

.card {
  background: #f4f4f4;
  color: #333333;
  font-size: 1rem;
  padding: 16px;
}

.card .card-title {
  font-size: 18px;
  color: #333333;
}

.card--featured .card-title {
  font-size: 17px;
  font-weight: 700 !important;
}

.legacy-banner {
}

.footer {
  background: #f5f5f5;
  color: #444444;
  font-size: 14px;
}

Zurück kommt eine Ergebnisseite, gruppiert nach denselben Kategorien wie in der Metrik-Dokumentation: Stylesheet, Atrules, Rules, Selectors, Declarations, Properties und Values. Es gibt weit über hundert Metriken. Die folgenden fünf sind diejenigen, aus denen ein Commit wird.

Was sagen eindeutige Farben und Font-Sizes aus?

Die Differenz zwischen Gesamtzahl der Farben und eindeutigen Farben zeigt, wie oft jede Farbe wiederverwendet wird, und die Differenz zwischen eindeutigen Farben und der Palette, die Ihr Design-System definiert, zeigt, wie weit der Code vom Design abgedriftet ist. Der Analyzer zählt beides und liefert die vollständige Liste der gefundenen eindeutigen Farben; Font-Sizes werden genauso behandelt.

Von Hand gelesen enthält das Fixture sechs unterschiedliche Hex-Werte: #f5f5f5 und #f4f4f4 für Flächen sowie #333333, #343434, #222222, #444444 für Text. Ein Design-System für diese Komponente hatte mit ziemlicher Sicherheit eine Flächenfarbe und zwei Textfarben vorgesehen. Bei der Typo-Skala sieht es noch schlechter aus: 16px, 15px, 1rem, 18px, 17px, 14px sind sechs Werte, so wie sie geschrieben sind – und 16px und 1rem lösen sich ohnehin meist zur selben Pixelgröße auf.

Die Lösung heißt Konsolidierung, nicht Löschung. Nahezu identische Grautöne zusammenzuführen bedeutet nicht, Regeln zu entfernen; es bedeutet, jedes Literal durch das nächstliegende Token zu ersetzen und die Regel weiterhin ihre Aufgabe erfüllen zu lassen:

:root {
  --color-surface: #f5f5f5;
  --color-text: #333333;
  --color-text-muted: #444444;
  --font-size-sm: 0.875rem;
  --font-size-base: 1rem;
  --font-size-lg: 1.125rem;
}

.card {
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--font-size-base);
  padding: 16px;
}

Drei Farb-Tokens ersetzen sechs Literale; drei Größen-Tokens ersetzen sechs. Das separate Design-Tokens-Tool von Project Wallace extrahiert Kandidaten für Farben und Font-Sizes aus bestehendem CSS – bei einem echten Stylesheet ein deutlich schnellerer Ausgangspunkt, als die Liste von Hand durchzugehen.

Spezifität: Ausschläge zählen mehr als das Maximum

Ein Selektor mit hoher Spezifität am Ende eines Stylesheets ist ein lokales Problem, aber einer in der Mitte zwingt jede spätere Regel, die ihn überschreiben muss, auf dasselbe Niveau zu klettern – und genau dieses Klettern lässt id-Selektoren und !important-Flags anwachsen. Harry Roberts’ Specificity Graph macht dasselbe Argument visuell: Die Kurve sollte gegen Ende sanft ansteigen, und jeder Ausschlag ist ein Preis, den alles Nachfolgende bezahlt.

Der Analyzer meldet die Spezifität als dreiteiligen Wert aus id, class und type über Maximum selector specificity, Total selectors having maximum specificity und Top specificity selectors, dazu Total id selectors, Total !important declarations und Ratio of !important declarations.

Das Fixture zeigt den Mechanismus im Kleinen. #site-header .nav-link liegt bei (1,1,0). Das spätere .nav-link:hover bei (0,2,0) kann das nicht übertreffen, also griff ein Beitragender zu !important. Ein id-Selektor erzeugte ein !important-Flag, und das zweite Flag an .card--featured .card-title übertrumpft eine Regel, die font-weight überhaupt nie gesetzt hat.

Die Anzahl der id-Selektoren und die Anzahl der !important-Deklarationen sind die beiden Spezifitätszahlen, die ein Team Commit für Commit senken und nach jeder Änderung neu messen kann. Ändert man im Fixture das Markup von id="site-header" zu class="site-header", flachen beide Header-Regeln auf (0,1,0) und (0,2,0) ab, und beide !important-Flags werden überflüssig.

Doppelte Deklarationen und leere Regeln

Eine leere Regel kostet Bytes und einen Selektor-Match, ändert aber nichts an dem, was der Nutzer sieht – ihr Entfernen ist deshalb die eine Audit-Korrektur, die nie eine visuelle Regressionsprüfung braucht. Bei doppelten Deklarationen sieht es anders aus: Dieselbe Absicht zweimal geschrieben ist ein Code Smell, aber das Löschen der falschen Kopie verändert die Kaskade.

Der Analyzer zählt Total empty rules direkt; .legacy-banner {} ist der einzige Fall im Fixture, und der fliegt raus. Eine eigenständige Metrik für doppelte Deklarationen gibt es nicht. Lesen Sie Total declarations gegen Total unique declarations und behandeln Sie die Differenz als Anzahl der Duplikate – wobei zu beachten ist, dass die Dokumentation weiterhin offenlässt, ob Whitespace oder Formatierung zwei Deklarationen unterscheidbar macht.

color: #333333 taucht in drei Regeln des Fixtures auf. Der richtige Schritt ist nicht, zwei Kopien zu löschen, sondern alle drei über var(--color-text) zu führen. Damit wird die Wiederholung als gemeinsame Entscheidung sichtbar statt als Zufall.

Warum verschleiert die Gzip-Dateigröße ein aufgeblähtes Stylesheet?

Gzip komprimiert Wiederholungen effizient, deshalb kann ein Stylesheet voller doppelter Deklarationen eine schmeichelhafte komprimierte Größe ausweisen, während seine unkomprimierte Größe – die Bytes, die der Browser tatsächlich parst – weiter wächst. Der Analyzer meldet Uncompressed filesize, Gzip filesize und Gzip filesize compression ratio gemeinsam.

Ein steigendes Kompressionsverhältnis ist das verräterische Signal: Es bedeutet, dass das Stylesheet repetitiver wird, nicht kleiner. Was die unkomprimierte Größe bewegt, ist die Anzahl der Regeln und Deklarationen – deshalb reduziert die oben beschriebene Konsolidierungsarbeit sie als Nebeneffekt. Die Dateigröße ist eine Diagnosegröße, die man nach den anderen Korrekturen liest, kein Ziel, das man für sich allein optimiert.

Ein Stylesheet über Releases hinweg verfolgen

Um ein Stylesheet über Releases hinweg zu verfolgen, speichern Sie das rohe CSS jedes Releases neben seinen Analyzer-Ergebnissen und führen Sie jede Analyse mit demselben Prettify-Zustand erneut aus. Der CSS Diff Viewer formatiert zwei eingefügte Stylesheets und vergleicht sie Zeile für Zeile im Browser – so sehen Sie, wo sich die Anzahl der eindeutigen Farben oder der id-Selektoren verändert hat.

Fazit

Ein Stylesheet-Audit rechtfertigt seinen Zeitaufwand, wenn sich jede Zahl auf eine Änderung abbilden lässt: eindeutige Farben und Font-Sizes auf Tokens, id-Selektoren und !important-Flags auf flachere Spezifität, leere Regeln auf Löschung, Duplikate auf gemeinsame Deklarationen und die Dateigröße auf eine Kontrolle, ob der Rest gewirkt hat. Fügen Sie Ihr größtes Produktions-Stylesheet in den Analyzer ein, notieren Sie diese fünf Zahlen und öffnen Sie pro Zahl einen Pull Request.

FAQs

Kann ich den Project-Wallace-Analyzer über die Kommandozeile oder in der CI ausführen?

Ja. Das npm-Paket wallace-cli führt denselben Analyzer im Terminal aus: Installieren Sie es mit npm install wallace-cli, führen Sie dann wallace path/to/styles.css aus oder leiten Sie CSS über stdin hinein, und ergänzen Sie das Flag --json für maschinenlesbare Ausgabe in CI-Skripten. Version 4.x der CLI setzt Node 20.12 oder neuer voraus. Für die programmatische Nutzung importieren Sie die Funktion analyze aus @projectwallace/css-analyzer, einem reinen ESM-Paket, das sowohl in Node als auch im Browser läuft.

Sollte ich meine Sass- oder Tailwind-Quelldateien analysieren oder das kompilierte CSS?

Analysieren Sie das kompilierte CSS, das Ihre Nutzer erhalten, nicht die Sass-, Less- oder Tailwind-Quelle. Variablen, Mixins und @extend werden zur Build-Zeit expandiert, deshalb geben Quelldateien eindeutige Farben, Selektorzahlen und Dateigröße falsch wieder. Das Stylelint-Plugin von Project Wallace sagt dasselbe darüber, worauf man es ansetzen sollte: auf das Bundle, das Sie ausliefern, denn Zählwerte eindeutiger Werte und die darauf aufbauenden Verhältnisse beschreiben die ausgelieferte Datei, nicht die Quelle. Der URL-Modus ruft ohnehin bereits die gebauten Stylesheets ab, die eine Site ausliefert.

Was ist der Unterschied zwischen dem Project Wallace CSS Analyzer und dem CSS-Code-Quality-Tool?

Der CSS Analyzer liefert Rohmetriken; das CSS-Code-Quality-Tool nimmt diese Ausgabe, führt eigene Prüfungen darüber aus und verdichtet das Ergebnis zu drei Scores von jeweils maximal 100 Punkten – für Performance, Maintainability und Complexity. Nutzen Sie den Analyzer, wenn Sie eine Zahl bis zu einer konkreten Regel zurückverfolgen müssen, und Code Quality, wenn Sie eine bewertende Zusammenfassung für ein Team brauchen. Beide akzeptieren eine URL, hochgeladene Dateien oder eingefügtes CSS.

Wie verhindere ich, dass eindeutige Farben oder die Spezifität nach einem Audit wieder zurückfallen?

Fügen Sie @projectwallace/stylelint-plugin zu Ihrer Stylelint-Konfiguration hinzu. Es liefert über 60 Regeln, die auf derselben Analyse-Engine aufbauen, darunter projectwallace/max-unique-colors, und sein holistisches Preset beurteilt die Datei als Ganzes (Summen, Durchschnitte, Verhältnisse, Eindeutigkeit), statt einen Knoten nach dem anderen zu prüfen. Ein empfohlenes Preset bringt Sie mit einer einzigen extends-Zeile zum Laufen. Führen Sie es in der CI gegen das gebaute CSS-Bundle aus, damit ein Pull Request, der einen siebten Grauton hinzufügt, vor dem Merge fehlschlägt.

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — self-hosted, with full data ownership.

Star on GitHub

We use cookies to improve your experience. By using our site, you accept cookies.