CD-Konformität: Inline-Styles raus, alle Formatierung über zentral definierte CSS-Klassen #184

Open
opened 2026-05-07 09:34:50 +02:00 by tobias · 1 comment
Owner

Problem

Die Webseite war ursprünglich nach klarem Corporate Design (v2.css + Tokens in tokens.css) gestylt — Farben, Typografie, Abstände kamen aus zentral definierten Variablen und Klassen. Im Laufe der schnellen Iteration (Score-Hero, Marker-Pills, neue Tabs auf /auswertungen, Modal-Dialoge) sind viele neue Elemente mit Inline-Styles entstanden, die das CD umgehen.

Konkrete Stellen, die jetzt schon auffallen:

  • app/templates/v2/screens/antrag_detail.html: dutzende style="..."-Attribute (Modal, Vote-Block, Comment-Form, Aktions-Links, News-Box)
  • app/templates/v2/screens/auswertungen.html: viele Inline-Styles in den vier Tabs
  • app/templates/v2/screens/aktuelle_themen.html: PM-Modal mit komplettem Inline-Styling
  • Farben hartkodiert (#2da44e, #cf222e, …) statt über --ecg-*-Tokens (gerade in Vote-Pills, Heuchelei-Marker, Cluster-Visualisierung)

Das hat zwei Konsequenzen:

  1. CD-Drift: Wenn sich der Markenfarbton ändert (z.B. Refresh des GWÖ-Brandings), müssen 50+ Stellen einzeln angefasst werden statt eine tokens.css-Variable.
  2. Inkonsistenz: Zwei Heuchelei-Marker auf zwei verschiedenen Screens haben minimal unterschiedliche Paddings/Borders, weil sie unabhängig inline gestylt wurden.

Frage / Recherche

Gibt es ein konsequentes Framework, das das erzwingt? Konkret gemeint: ein Mechanismus analog zu "Word-Formatvorlagen" — ein Stylesheet/Tooling, das verhindert, dass irgendwer im Template ein style="color:#…" schreibt.

Kandidaten zur Bewertung:

  • Stylelint mit declaration-no-important/selector-pseudo-class-no-unknown/csstools/no-style-attribute — Linter-Regel, die style="" in HTML/Jinja-Templates verbietet (über htmlhint oder eslint-plugin-jinja).
  • Tailwind-CSS — utility-first; jede Klasse ist Token-basiert. Aber: bricht das bestehende v2.css-System und ist konzeptionell gegenläufig zum "Component-Klassen"-Ansatz.
  • Eigene Pre-Commit-Hook: grep-Regel style="[^"]+" in Templates → Reject, mit Whitelist für SVG-Icons/Charts (wo Inline-Styles unvermeidbar sind, weil sie dynamisch berechnet werden).
  • CSS Custom Properties + Component-Klassen-Bibliothek (aktueller Stand, aber ohne Lint): saubere Variante wäre, die Inline-Styles systematisch in benannte Klassen zu überführen und ein einfaches Lint-Skript zu schreiben.

Empfohlener Ansatz (zur Diskussion)

  1. Audit: einmal alle style=""-Vorkommen in app/templates/v2/** zählen + nach Verwendungszweck clustern (Layout, Color, Typography, ad-hoc).
  2. Migration in Wellen: pro Screen die Inline-Styles in benannte Klassen überführen, gleichzeitig Tokens zentralisieren.
  3. Lint-Hook: neuen Pre-Commit-Hook (tools/lint-no-inline-styles.sh), der style="" in Templates verbietet — mit Whitelist (z.B. dynamische Charts.js-Container).
  4. CD-Reference-Page: eine Doku-Seite (z.B. /methodik#cd oder eigene /cd), die alle Klassen + Tokens als Living Style Guide zeigt — Bürgerinnen können das ignorieren, Entwickler:innen können dort nachschauen statt erfinden.

Aufwand (AI-Zeit)

  • Audit + Cluster: kurz (1-2 Bash-Sessions)
  • Migration pro Screen: mittel (5–8 Screens × 30–60 min = ein Tag intensive Arbeit)
  • Lint-Hook + CI: kurz
  • Living Style Guide: mittel

Nicht-Ziele

  • Komplettes Frontend-Framework wechseln (kein Tailwind, kein Bootstrap)
  • Visuelle Änderungen — die User-Wahrnehmung soll gleich bleiben, nur die Code-Wartbarkeit besser werden
## Problem Die Webseite war ursprünglich nach klarem Corporate Design (`v2.css` + Tokens in `tokens.css`) gestylt — Farben, Typografie, Abstände kamen aus zentral definierten Variablen und Klassen. Im Laufe der schnellen Iteration (Score-Hero, Marker-Pills, neue Tabs auf /auswertungen, Modal-Dialoge) sind viele neue Elemente mit **Inline-Styles** entstanden, die das CD umgehen. Konkrete Stellen, die jetzt schon auffallen: - `app/templates/v2/screens/antrag_detail.html`: dutzende `style="..."`-Attribute (Modal, Vote-Block, Comment-Form, Aktions-Links, News-Box) - `app/templates/v2/screens/auswertungen.html`: viele Inline-Styles in den vier Tabs - `app/templates/v2/screens/aktuelle_themen.html`: PM-Modal mit komplettem Inline-Styling - Farben hartkodiert (`#2da44e`, `#cf222e`, …) statt über `--ecg-*`-Tokens (gerade in Vote-Pills, Heuchelei-Marker, Cluster-Visualisierung) Das hat zwei Konsequenzen: 1. **CD-Drift**: Wenn sich der Markenfarbton ändert (z.B. Refresh des GWÖ-Brandings), müssen 50+ Stellen einzeln angefasst werden statt eine `tokens.css`-Variable. 2. **Inkonsistenz**: Zwei Heuchelei-Marker auf zwei verschiedenen Screens haben minimal unterschiedliche Paddings/Borders, weil sie unabhängig inline gestylt wurden. ## Frage / Recherche Gibt es ein konsequentes Framework, das das **erzwingt**? Konkret gemeint: ein Mechanismus analog zu "Word-Formatvorlagen" — ein Stylesheet/Tooling, das verhindert, dass irgendwer im Template ein `style="color:#…"` schreibt. Kandidaten zur Bewertung: - **Stylelint mit `declaration-no-important`/`selector-pseudo-class-no-unknown`/`csstools/no-style-attribute`** — Linter-Regel, die `style=""` in HTML/Jinja-Templates verbietet (über `htmlhint` oder `eslint-plugin-jinja`). - **Tailwind-CSS** — utility-first; jede Klasse ist Token-basiert. Aber: bricht das bestehende v2.css-System und ist konzeptionell gegenläufig zum "Component-Klassen"-Ansatz. - **Eigene Pre-Commit-Hook**: grep-Regel `style="[^"]+"` in Templates → Reject, mit Whitelist für SVG-Icons/Charts (wo Inline-Styles unvermeidbar sind, weil sie dynamisch berechnet werden). - **CSS Custom Properties + Component-Klassen-Bibliothek** (aktueller Stand, aber ohne Lint): saubere Variante wäre, die Inline-Styles systematisch in benannte Klassen zu überführen und ein einfaches Lint-Skript zu schreiben. ## Empfohlener Ansatz (zur Diskussion) 1. **Audit**: einmal alle `style=""`-Vorkommen in `app/templates/v2/**` zählen + nach Verwendungszweck clustern (Layout, Color, Typography, ad-hoc). 2. **Migration in Wellen**: pro Screen die Inline-Styles in benannte Klassen überführen, gleichzeitig Tokens zentralisieren. 3. **Lint-Hook**: neuen Pre-Commit-Hook (`tools/lint-no-inline-styles.sh`), der `style=""` in Templates verbietet — mit Whitelist (z.B. dynamische Charts.js-Container). 4. **CD-Reference-Page**: eine Doku-Seite (z.B. `/methodik#cd` oder eigene `/cd`), die alle Klassen + Tokens als Living Style Guide zeigt — Bürgerinnen können das ignorieren, Entwickler:innen können dort nachschauen statt erfinden. ## Aufwand (AI-Zeit) - Audit + Cluster: kurz (1-2 Bash-Sessions) - Migration pro Screen: mittel (5–8 Screens × 30–60 min = ein Tag intensive Arbeit) - Lint-Hook + CI: kurz - Living Style Guide: mittel ## Nicht-Ziele - Komplettes Frontend-Framework wechseln (kein Tailwind, kein Bootstrap) - Visuelle Änderungen — die User-Wahrnehmung soll **gleich bleiben**, nur die Code-Wartbarkeit besser werden
Author
Owner

Anti-Regression-Wache live (Commit 57e11b3). Statt alle 1322 Inline-Styles in einer Sitzung zu migrieren, ist jetzt eine Wache aktiv:

  • tools/audit_inline_styles.py (CLI für Audit + Baseline)
  • tools/inline_styles_baseline.json (IST-Zählung eingefroren)
  • tests/test_inline_styles_baseline.py (3 Tests, pro Datei + global)

Cluster: 625 layout, 323 typography, 262 color, 112 sonstige.
Top-Brennpunkte: index.html (463 — Classic-UI Legacy), auswertungen.html (125), antrag_detail.html v2 (119), aktuelle-themen.html (82).

Issue bleibt offen für Migration-Wellen. Mit der Wache wächst die Anzahl nicht mehr; pro PR kann sie schrumpfen, indem ein Template umgestellt + Baseline neu eingefroren wird.

Living Style Guide explizit vertagt.

**Anti-Regression-Wache live** (Commit 57e11b3). Statt alle 1322 Inline-Styles in einer Sitzung zu migrieren, ist jetzt eine Wache aktiv: - tools/audit_inline_styles.py (CLI für Audit + Baseline) - tools/inline_styles_baseline.json (IST-Zählung eingefroren) - tests/test_inline_styles_baseline.py (3 Tests, pro Datei + global) Cluster: 625 layout, 323 typography, 262 color, 112 sonstige. Top-Brennpunkte: index.html (463 — Classic-UI Legacy), auswertungen.html (125), antrag_detail.html v2 (119), aktuelle-themen.html (82). Issue bleibt offen für Migration-Wellen. Mit der Wache wächst die Anzahl nicht mehr; pro PR kann sie schrumpfen, indem ein Template umgestellt + Baseline neu eingefroren wird. Living Style Guide explizit vertagt.
Sign in to join this conversation.
No description provided.