Styling Discourse mit Variablen: Ein Plädoyer für einfachere Semantik

Fortsetzung der Diskussion von Styling Discourse with variables: Show & Tell:

Ich schätze die Bemühungen, die Theming-Erfahrung von Discourse zu verbessern, sehr! Ich bin jedoch nicht ganz davon überzeugt, dass der Ansatz, viele CSS-Variablen hinzuzufügen, wie im obigen Thema geteilt, die optimale Lösung ist. Ich wollte dazu ein paar Gedanken teilen.

Ich habe diesen Ansatz selbst mit der Canvas Theme Template experimentiert, die im Wesentlichen eine Sammlung von einstellbaren Variablen für die Erstellung von Basisthemen bereitstellt:

:root {
  /* Layout */
  --d-max-width: 1110px;
  --canvas-nav-space: 0.75rem;
  --canvas-content-padding: 1.5rem;
  --canvas-topic-list-padding: 0.8em;

  /* Base Styles */
  --canvas-background: var(--secondary);
  --canvas-surface: var(--secondary);
  --canvas-border: 1px solid var(--primary-500);
  --canvas-border-light: 1px solid var(--primary-200);

  /* Border Radius */
  --d-border-radius: 2px;
  --d-border-radius-large: 2px;
  --d-button-border-radius: 2px;
  --d-input-border-radius: var(--d-button-border-radius);
  --d-nav-pill-border-radius: var(--d-button-border-radius);

  /* Button Styles */
  --canvas-button-padding: 0.5em 0.65em;
  --canvas-button-primary-padding: 0.5em 0.65em;

  /* Header */
  --canvas-header-height: 4rem;
  --canvas-header-background: var(--header_background);
  --canvas-header-border: none;
  --canvas-header-shadow: var(--shadow-header);

  /* Sidebar */
  --d-sidebar-width: 17em;
  --d-sidebar-background: var(--secondary);
  --canvas-sidebar-border: 1px solid var(--primary-low);
  --canvas-sidebar-scrollbar: var(--scrollbarWidth);
  --d-sidebar-row-height: 2.2em;
  --d-sidebar-highlight-background: var(--primary-low);

  /* Und viele mehr... */
}

Während dies für einfache Anpassungen recht gut funktioniert, bin ich bei der Skalierung dieses Ansatzes auf mehrere Einschränkungen gestoßen:

Kognitiver Aufwand und Auffindbarkeit

Eine umfangreiche Liste von Variablen erfordert im Wesentlichen eine Nachschlagetabelle. Dies fühlt sich von der Art und Weise, wie man typischerweise in einem komponenten-basierten Framework arbeitet, getrennt an, wo man tatsächlich erwartet, Komponenten zu stylen. Und vielleicht bin das nur ich, aber ich habe das Gefühl, dass das mentale Modell von “Ich möchte diese Komponente stylen” zu “Ich muss den richtigen Variablennamen finden” verschoben wird.

Mangelnde Kaskadierungslogik

Die aktuelle Implementierung weist hartcodierte Werte direkt Variablen zu, ohne eine ordnungsgemäße Kaskadenhierarchie zu etablieren:

--d-sidebar-link-color: var(--primary-high);
--d-nav-background-color--active: transparent;
--table-border-width: 1px;

Das bedeutet, dass es keine Vererbung von allgemeineren Variablen wie --link-color oder --border-width gibt. Wenn ich systematische Änderungen vornehmen möchte, muss ich mehrere spezifische Variablen aktualisieren, anstatt einen grundlegenden Wert zu ändern.

Lücke zwischen Design und Entwicklung

Ich denke, der Ansatz schafft Reibung bei der Arbeit zwischen Design-Tools (wie Figma) und der Implementierung. Designsysteme verwenden typischerweise semantische Variablen, die nicht eins zu eins mit diesen sehr implementierungsspezifischen Variablen übereinstimmen.

Ein alternativer Ansatz, der die Komponentenarchitektur nutzt

Ich denke, wir könnten das gleiche Ziel auf natürlichere Weise erreichen, indem wir grundlegende semantische Variablen mit zuverlässigem Komponentenziel kombinieren. Anstatt einer langen Liste spezifischer Variablen, was wäre, wenn wir uns auf eindeutige und konsistent benannte Komponentenklassen in ganz Discourse verlassen könnten? Dinge wie .d-sidebar, .d-topic-list, .d-header.

Kombinieren Sie dies dann mit einer kleineren Menge an grundlegenden Variablen, die tatsächlich so kaskadieren, wie CSS funktionieren soll:

/* Setzt die Designgrundlage */
:root {
  --d-border-width: 2px;
  --d-surface-color: #3498db;
  --d-space-1: 1rem;
}

/* Überschreiben auf Komponentenebene, wenn Sie müssen */
.d-topic-list,
.d-sidebar {
  --d-border-width: 1px;
}

Für mich fühlt sich das mehr so an, wie CSS natürlich funktioniert. Ich lege meine globalen Stile fest und verfeinere sie dann, wo nötig. Wenn ich ändern möchte, wie Rahmen in der gesamten App aussehen, ändere ich eine Variable. Wenn ich möchte, dass die Seitenleiste anders aussieht, ziele ich gezielt auf die Seitenleiste.

3 „Gefällt mir“

Nun, ich denke, wie CSS auf natürliche Weise funktionieren würde, ist einfach, die Variablen zu überspringen und Folgendes zu tun:

/* Legen Sie die Design-Grundlage fest */
body {
  border-width: 2px;
  background-color: #3498db;
  margin: 1rem;
}

/* Überschreiben Sie auf Komponentenebene, wenn Sie müssen */
.d-topic-list,
.d-sidebar {
  border-width: 1px;
}

Vielleicht bin ich einfach alt.
Das wirkliche Problem ist dies

Beispiel: Einfach .btn oder button anvisieren:

.btn {
    border: 1px solid red;
}

verfehlt die Beitrags-Buttons, zielt aber auf den Link „Ansichten“ und das Hamburger-Menü.

1 „Gefällt mir“

Es gibt gute Gründe, Variablen zu verwenden, vielleicht sollten wir hier nicht darauf eingehen. Es ist jedoch ein guter Punkt, nicht über die Natur von CSS zu streiten. Ich hätte das besser formulieren sollen: Es geht nicht um die Natur von CSS, sondern um Best Practices für das Styling eines komponentenbasierenden Frameworks. Und ich stimme vollkommen zu, dass Schaltflächen ein weiteres gutes Beispiel dafür sind, wie diese nicht richtig angewendet werden können.

Wenn man das Gesamtbild betrachtet, gab es eine konzertierte Anstrengung, die JavaScript-Seite des Frontend-Frameworks zu modernisieren. Und ich denke, das war ein voller Erfolg. Die Arbeit mit sauberen Standards und gut strukturierten Klassen macht jetzt wirklich Spaß. Für mich als Designer hat es auch Möglichkeiten eröffnet, neue Frontend-Komponenten einfacher und effizienter zu erstellen.

Ich kann jedoch nicht umhin zu denken, dass es kein ähnliches Engagement gibt, das Designsystem auf den gleichen Standard zu bringen. Während das Hinzufügen von CSS-Variablen für jeden Aspekt sicherlich performanter und sauberer ist als der aktuelle Ansatz, fühlt es sich immer noch so an, als würde man die tieferen architektonischen Probleme vermeiden: eine Codebasis voller übermäßig spezifischer Deklarationen und ohne klare, komponentenbezogene Stile. Dies fühlt sich wie eine “einfachere” Lösung an, die das schwierigere Problem vermeidet: die vollständige Ausrichtung der Styling-Architektur an das modulare Design des Frameworks.

Ich verstehe, dass dies viel Arbeit und Probleme mit der Abwärtskompatibilität mit sich bringen würde. Aber das Team hat diese Herausforderungen auf der JavaScript-Seite erfolgreich gemeistert. Wenn JavaScript weiterhin deutlich mehr Ressourcen als Styles erhält, wird sich dieser Unterschied in den endgültigen Designs widerspiegeln. Und die Benutzer werden den Unterschied spüren, auch wenn sie nicht artikulieren können, warum.

Ich würde mir einfach wünschen, dass die gleiche Modernisierungsenergie in die CSS-Architektur fließt, denn ich bin überzeugt, dass die langfristigen Vorteile für die Entwickler- und Benutzererfahrung transformativ wären.

5 „Gefällt mir“

Der Ansatz, den wir verfolgt haben, fühlt sich so an, als ob er dem entspricht, was Sie beschreiben. Daher fällt es mir schwer zu verstehen, wie Sie sie anders implementiert hätten. Ich bin aber definitiv offen für Feedback und schätze die Perspektive, die Sie einbringen.

Zum Beispiel würde eine Änderung an etwas wie --space die gesamte Abstände in der App ändern. Sie könnten es auch so anpassen, dass es nur die Abstände in der Themenliste oder der Seitenleiste mit ähnlichen Ansätzen wie von Ihnen beschrieben beeinflusst.

Das stimmt für einige Elemente, aber nicht für andere. Jede weitere von Ihnen geteilte Beispiele wären großartig!

Das ist definitiv ein Problem. Ein Ansatz, den wir im Sinn haben (zumindest vorerst experimentell), ist ein Editor, der dem ähnelt, was shadcn hier macht:

Auch wenn es kein perfekter Ansatz ist, glaube ich, dass er uns näher daran bringt, es für Leute einfacher zu machen, die nicht wissen, wie man den Inspektor benutzt / auf Meta für Dokumentation zugreift / CSS verwendet.

Was einen stärker komponentenorientierten Ansatz betrifft, so ist das etwas, das wir schließlich erreichen wollen, aber Discourse wurde von Anfang an nicht mit Blick auf ein komponentenorientiertes Design erstellt, und darauf zu warten, bevor nutzbare Variablen hinzugefügt werden, stand nicht zur Debatte.

Das Hinzufügen einiger Klassen, um dies in bestimmten Abschnitten einfacher zu implementieren, klingt nach einem guten Weg für die Benutzerfreundlichkeit.


Ich stimme Ihnen zu :+1:

2 „Gefällt mir“

Die kurze Antwort ist: Tu das nicht :sweat_smile:

Du bist viel besser damit bedient, eine sekundäre Schaltflächenklasse anzuvisieren, btn-default, btn-primary, btn-flat – diese sekundären Klassen repräsentieren einen visuellen Schaltflächentyp.

.btn und button sind allgemeiner „dies ist eine Schaltfläche“ als jedes spezifische Aussehen.

4 „Gefällt mir“

Das ist genau das, was es ist. Wir haben derzeit nicht die Bandbreite, um eine mehrjährige Neufassung unseres HTML und CSS sowie aller von uns gepflegten Themes in Angriff zu nehmen, insbesondere wenn man bedenkt, dass wir mit der mehrjährigen Reise der Ember-Updates noch nicht fertig sind.

5 „Gefällt mir“