Aufbau & Pflege von OUI (Optimizely's UI-Bibliothek): Teil 1/2

Avatar of Tom Genoni
Tom Genoni am

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

Der folgende Beitrag stammt von Tom Genoni. Tom wird uns die Denkweise und den Prozess hinter der neuen UI-Bibliothek / dem Sass-Framework von Optimizely vorstellen. Teil 2 von Daniel O’Connor befasst sich mit einigen technischen Aspekten und Integrationsdetails.

Als ich anfing, an Webprojekten zu arbeiten, wurden Stylesheets als notwendiges Übel betrachtet. Es war weder eine *echte* Sprache, die von einem Informatiker ernst genommen wurde, noch einfach genug, damit ein Designer sie vollständig beherrschen und verstehen konnte. Bei wenigen Best Practices war die Organisation von CSS immer ad hoc – „Schriftstile in diesem Abschnitt, Farben in diesem Abschnitt“ – und jede Firma machte es anders. Aber als Webanwendungen und die Teams, die sie entwickelten, immer größer und komplexer wurden, wurde es schwieriger, die explodierenden Codebasen zu verwalten und gleichzeitig die Konsistenz über Teams und Projekte hinweg zu wahren.

Eines der ersten beliebten CSS-Frameworks, das zur Bewältigung dieses Problems aufkam, war Bootstrap. Viele ähnliche Frameworks folgten, aber der Zweck war immer derselbe: Anstatt jedes Mal CSS von Grund auf neu zu schreiben, beginnt man mit einem gestylten Satz der gängigsten Komponenten – Grids, Buttons, Formularelemente, Breadcrumbs –, die browserübergreifend kompatibel sind und leicht zu größeren Interfaces kombiniert werden können.

Bei Optimizely haben wir unser eigenes Sass-Framework namens OUI (ausgesprochen wie das französische Wort für „ja“) entwickelt und pflegen es aktiv. Es basiert auf der Arbeit unzähliger Mitglieder der Web-Community, darunter Mark Otto, Jonathan Snooks, Nicole Sullivan und Harry Roberts, sowie auf den Philosophien von skalierbarem, objektorientiertem CSS und HTML, die von BEM und SMACSS vertreten werden.

Abbildung 1: Lernen Sie Louis kennen, das offizielle Maskottchen von OUI.

Die fortlaufenden Ziele von OUI sind es, Code bereitzustellen, der...

  • Abstrahiert. Komponentennamen sollten nicht aus dem Inhalt abgeleitet werden, den sie enthalten. Klassennamen sollten strukturelle Bedeutung vermitteln.
  • Wiederverwendbar. Komponenten sollten generisch genug sein, um sie auf der gesamten Website wiederverwenden zu können. Sie sollten keine Annahmen darüber treffen, auf welcher Seite/Ansicht sie verwendet werden. In einem Bereich gelöste Probleme sollten leicht anderswo angewendet werden können.
  • Kombinierbar. Komponenten sollten miteinander kombiniert werden können, um größere Blöcke zu erstellen.
  • Mit Variablen betrieben. Alle gängigen Designelemente – Farben, Schriften, Abstände, Schatten – sollten mithilfe vordefinierter Variablen definiert werden.
  • Skalierbar. Die Wiederverwendung von Mustern bedeutet, dass neue Elemente schneller und mit minimalem zusätzlichem CSS erstellt werden können.
  • Konsistent. Entwickler können den Code des anderen besser lesen und tragen zu zuverlässigeren Endnutzererlebnissen bei.
  • Klein und DRY. Da wir Low-Level-Komponenten wiederverwenden, um größere Objekte zu erstellen, reduzieren wir CSS-Bloat. Weniger Code bedeutet weniger Fehler.

In diesem Beitrag werde ich die praktischen Schritte und die Partnerschaften mit Ingenieuren und Designern erörtern, die zu seiner Erstellung erforderlich waren, sowie einige Probleme, auf die wir dabei gestoßen sind. In Teil II wird mein Kollege Daniel O’Connor, ein weiterer UI-Ingenieur, die technischen Details beschreiben, wie wir ihn testen, versionieren und in Projekte integrieren.

Phase 1: Holen Sie Ihre Designer mit ins Boot

Die wohl wichtigste Phase bei der Erstellung einer UI-Bibliothek ist die enge Zusammenarbeit mit Ihrem Designteam. Das Designen mit einem Framework erfordert oft eine Verlagerung des Arbeitsablaufs weg von Pixel-perfekten Mockups und kann zu einem scheinbaren Verlust an Designfreiheit führen. Glücklicherweise gibt es einen Weg, dies anzugehen: Auditieren Sie Ihre Website und präsentieren Sie Ihre Ergebnisse.

Widmen Sie ein oder zwei Tage dem Erstellen von Screenshots Ihrer Website. Durchsuchen Sie jeden Winkel nach allen Vorkommen von Buttons, Formularen, Tabellen, Schriftgrößen, Farben, Tags, Icons usw. und gruppieren Sie sie. Was Sie wahrscheinlich aufdecken werden, wird Ihre Designer erschrecken lassen: Buttons aller Formen und Größen, Überschriften mit wenig Regelmäßigkeit, 27 Blautöne und viele andere Beispiele für gut gemeinte, aber schlecht umgesetzte Ideen. Wenn Sie Ihre Designer für die Konsolidierung dieser Inkonsistenzen verantwortlich machen, werden sie zu Partnern bei der Erstellung des Frameworks und Verbündeten bei der Mobilisierung anderer für diese Anstrengung.

Phase 2: Zuständigkeit für das Frontend

Entscheiden Sie mit Ihrem Engineering-Team, wer für das visuelle Frontend „zuständig“ ist. Da die CSS und das HTML Ihres Frameworks miteinander verbunden sind, haben wir festgestellt, dass es wichtig ist, eine kleinere Gruppe zu haben, die mit den Mustern des Frameworks vertraut ist und dafür verantwortlich ist, Code an oft dankbare Ingenieure zu liefern, die sich nicht mehr mit widerspenstigen z-Indizes herumschlagen müssen.

Bei Optimizely sind es unsere UI-Ingenieure, die offiziell Teil des Designteams sind, die diese Rolle ausfüllen. Mit dieser engeren Kontrolle haben wir die Menge an neu zu schreibendem CSS drastisch reduziert, unser Code ist sauberer und konsistenter, und wir erleben weitaus weniger Fehler. Im Laufe der Zeit kann die Verantwortung für das Schreiben von HTML und CSS erweitert werden, wenn Ingenieure verstehen, wie sie die Bibliothek effektiv nutzen können, und wenn das Framework reift.

Phase 3: Identifizieren Sie Ihre Komponenten

Bootstrap enthält so ziemlich alles, was Sie zum Erstellen der meisten Websites benötigen. Aber vielleicht möchten Sie keine Breadcrumbs, oder vielleicht können Sie neuere CSS-Eigenschaften verwenden, da Ihre Browserunterstützung dies zulässt. In jedem Fall empfehlen wir, bestehende Frameworks zu referenzieren und eine Liste nur der Komponenten zu erstellen, die zur Abdeckung Ihrer Anwendungsfälle erforderlich sind. Indem Sie es selbst erstellen, identifizieren Sie potenzielle Problemstellen leichter und lernen dabei eine Menge.

OUI wurde mit nur den Komponenten und Variablen erstellt, die wir als universell bestimmt haben. Jedes Optimizely-Projekt, das OUI verwendet, fügt benutzerdefinierten CSS-Code darauf aufbauend hinzu, nur im Repository dieses Projekts. Dies ermöglicht es jedem Projekt, seine individuellen Designanforderungen zu erfüllen und OUI gleichzeitig schlank und unverändert zu halten. Wenn verschiedene Projekte ähnliche Komponenten einführen, haben wir die Möglichkeit, sie in OUI zu „graduieren“, obwohl dies selten vorkam. In Teil II beschreiben wir unser Integrations- und Versionssystem detaillierter.

Phase 4: Organisieren & Bauen

CSS-Präprozessoren waren ein Segen für die Organisation von Code, indem sie Teil-Dateien unterstützten, die nur das enthielten, was für eine bestimmte Komponente benötigt wurde. Aber es bleibt eine Herausforderung zu entscheiden, wie Dinge benannt und wohin sie platziert werden sollen. Mit OUI verwenden wir derzeit die folgende Struktur

  • _oui-partials.scss: Eine Zusammenfassung aller zu inkludierenden Teil-Dateien.
  • _oui-variables.scss: Variablen für praktisch alles. Dies beinhaltet eine benutzerdefinierte Funktion zum Abrufen von Werten aus verschachtelten Variablenobjekten.
  • oui.scss: Eine Root-Sass-Datei, die alle Zusammenfassungen enthält (nur zum Testen verwendet und nicht von Projekten referenziert, die OUI verwenden).
  • library: Drittanbieter-Bibliotheken (wir werden dies wahrscheinlich entfernen)
  • partials: Ein Verzeichnis aller Teil-Dateien.
    • elements: Mixins und Funktionen. Da wir node-sass für die Kompilierung verwenden, fügen wir auch die Mixins ein, die wir für Animationen, Tönungen und Präfixe benötigen, die normalerweise von Compass stammen würden.
    • base: Resets und minimale HTML-Elementstile (Links, Tabellen, Listen)
    • components: Low-Level-Elemente, die beim Erstellen von Objekten helfen (Grid, Media, Nav)
    • objects: Die vollständig geformten und gestylten Stücke (Buttons, Spinner, Dropdown)
    • trumps: Hilfsklassen für das Layout (Margen, Abstände, Schriftstil)
  • Im Sass verwenden wir keine IDs, die Selektor-Tiefe wird auf ein Minimum beschränkt, und die Quellreihenfolge hilft uns, die Spezifität niedrig zu halten. Sie können einen genaueren Blick in das OUI-Repository werfen.

    Phase 5: Dokumentieren & Verbreiten

    All diese Arbeit wird nicht dazu beitragen, Ihren Code zu optimieren, wenn niemand davon weiß oder wie man ihn benutzt. Hier sind einige Vorschläge, die OUI geholfen haben, bei Optimizely an Zugkraft zu gewinnen.

    1. Wählen Sie einen Codenamen. Wie jedes gute Ingenieursprojekt sollte Ihr Framework einen internen Codenamen haben. Es ist wahrscheinlich nichts, was man normalerweise bei CSS-Projekten macht, aber hey, dieses ist wichtig! Wenn es kurz genug ist, kann es als Präfix für die Benennung von Klassen verwendet werden.
    2. Bieten Sie gute Dokumentation. Wie jeder, der es versucht hat, weiß, ist das Schreiben und vor allem das Pflegen guter Dokumentation mit Codebeispielen, Nutzungshinweisen und einem Changelog nicht einfach. Unvollständige oder veraltete Dokumentation wird Ihre Entwickler nur frustrieren und kann das Vertrauen in das Projekt untergraben. Um dem entgegenzuwirken, benennen Sie Besitzer und legen Sie klare Erwartungen fest, was dokumentiert werden soll und wie es zugänglich und aktuell gehalten wird.

      Dies ist eine fortlaufende Herausforderung für uns, aber wir nähern uns langsam an. Daniel O’Connor war unzufrieden mit den bestehenden Lösungen und hat die Entwicklung eines robusten Live-Styleguide-Skripts namens ScribeSass geleitet, das Kommentare und Code in Sass-Quelldateien parst und Codebeispiele rendert. Wir werden das bald als Open-Source-Projekt veröffentlichen.

    3. Verbreiten. Mit Ihrem prägnanten Codenamen und der Dokumentation beginnen Sie, die Kunde zu verbreiten. Halten Sie Tech-Talks mit realen Beispielen, die die Geschwindigkeits- und Konsistenzvorteile der Wiederverwendung bestehender Stile und Muster demonstrieren. Wenn Sie das Budget dafür haben, erstellen Sie Aufkleber, T-Shirts oder Poster. Sammeln Sie jeden Monat Statistiken über die Größe, Regeln und Spezifität Ihres CSS sowie die Anzahl der Fehler und die Zeit, die Ihr Team mit deren Behebung verbracht hat, und teilen Sie die Ergebnisse. Wir sahen Rückgänge in allen Bereichen.

    Erkenntnisse

    Wie bei jedem Webprojekt haben wir unterwegs viele Fehler gemacht, Korrekturen vorgenommen und Ergänzungen hinzugefügt. Hier sind einige der Herausforderungen, denen wir uns gestellt haben, Anpassungen, die wir vorgenommen haben, und Probleme, mit denen wir uns weiterhin auseinandersetzen.

    • Namensräume. OUI funktionierte gut für neue Projekte, aber als wir anfingen, bestehende Projekte zu refaktorieren, erkannten wir, dass es zu Namenskollisionen bei Klassennamen kommen könnte. Um dies zu vermeiden, haben wir die Option einer namensraumbasierten Sass-Variable hinzugefügt, die den meisten Klassen in der endgültigen CSS-Ausgabe ein Präfix hinzufügt. Wenn zum Beispiel „oui-“ der Wert des Namensraums ist, wird die Klasse „.media“ zu „.oui-media“. Dies gab uns die Flexibilität, OUI freier mit Legacy-Code zu mischen.
    • Versionierung. Eine Zeit lang waren wir nicht überzeugt, dass der Aufwand für die Einführung einer formalen Versionierung die Mühe wert war. Nur wenige Projekte nutzten OUI und wir wollten die Hürden für Änderungen nicht zu hoch machen. Aber das Ausliefern von Korrekturen – insbesondere von solchen, die Brüche verursachen könnten – und die Kommunikation ihrer Auswirkungen wurde problematisch. Wir entschieden uns für die Einführung der Semantischen Versionierung, und mit Hilfe eines gut gepflegten Changelogs und einiger Gulp-Pakete können wir Funktionen hinzufügen und Fehler beheben, ohne Angst haben zu müssen, Projekte zu beeinträchtigen, die OUI verwenden. In Teil II wird Daniel O’Connor die Einrichtung der Versionierung detaillierter erläutern.
    • Sass-Mixins vs. Extend. Anfangs wurde OUI mit einer beträchtlichen Anzahl von extends eingerichtet. Wir waren uns ihrer Fallstricke bewusst und führten sie vorsichtig ein, immer mit Platzhaltern. Aber die Verwendung von extends kann CSS-Klassen auf unerwünschte Weise verschieben, und trotz unserer besten Bemühungen hatten wir schließlich einige Probleme mit Quellreihenfolge und Spezifität. Wir entschieden uns, viele der extends in Mixins umzuwandeln, und obwohl es etwas mehr Code ist, sind wir weniger besorgt über zukünftige Fallstricke.
    • Responsivität. Dies ist knifflig. Wir haben Media-Query-Mixins und optionale Breakpoints für einige unserer Muster, wie z. B. Grids, integriert. Da jedoch so vieles am responsiven Design zwangsläufig komplex ist und oft viel benutzerdefinierten Code erfordert, kann OUI über die grundlegenden Bausteine hinaus nicht viel mehr bieten. Trotz dieser inhärenten Herausforderung werden wir weiterhin Wege evaluieren, um das Framework responsiv freundlich zu gestalten.
    • Benutzerdefinierte vs. wiederverwendbare Muster.
      Bei der Erstellung neuer Designs und Layouts, die auf einem Spektrum zwischen der Wiederverwendung eines bestehenden Musters und einem völlig kundenspezifischen liegen, liegt es am UI-Ingenieur zu entscheiden, wie diese am besten erstellt werden. Letztendlich ist das Ziel des Aufbaus einer UI-Bibliothek, Ihre CSS-Codebasis so klein und überschaubar wie möglich zu halten, aber Sie müssen auch die Anforderungen und die Flexibilität berücksichtigen, die Ihre Marke und Produkte erfordern. Kann das Design leicht angepasst werden, um in ein bestehendes Muster zu passen? Wenn dies nicht der Fall ist, sollte es sich um ein neues Muster handeln oder ist es völlig einzigartig? Die Verhandlung darüber ist mehr Kunst als Wissenschaft und unterstreicht die Bedeutung von Zusammenarbeit und Kompromissen zwischen Designern und UI-Ingenieuren.
    • Halten Sie sich daran. Mit der Zeit ist es leicht, Standards schleifen zu lassen. Ein paar hartcodierte Werte und magische Zahlen hier und da werden Ihre Anwendung nicht zum Absturz bringen. Da jedoch viele CSS-Fehler aus den unbeabsichtigten Folgen von vor langer Zeit geschriebenem Code entstehen, ist es wichtig, diese kleinen Zeitbomben fernzuhalten. Diese Disziplin wird sich auszahlen.

    Ergebnisse bisher

    Obwohl der folgende Vergleich nicht ganz „Äpfel mit Äpfeln“ ist, stammen diese CSS-Statistiken* von zwei visuell ähnlich komplexen Produkten bei Optimizely. Das erste ist eine ältere Anwendung, die vor OUI entwickelt wurde, und das zweite nutzte ausschließlich OUI.

    Produkt ohne OUI Produkt mit OUI Ändern
    Gzip-Größe 101 KB 33 KB -68%
    Stylesheet-Größe 618 KB 193 KB -69%
    Regeln 3259 1757 -46%
    Selektoren 5183 2407 -54%
    Identifikatoren 21375 4009 -81%
    Deklarationen 9356 4429 -53%
    Spezifität pro Selektor 87 15 -83%
    Top-Selektor-Spezifität 641 50 -92%
    ID-Selektoren 3135 0 -100%

    * Die meisten Werte wurden mit Parker, einem „Stylesheet-Analyse-Tool“, generiert.

    Zusammenfassung

    Die Verwaltung eines Frameworks in Ihrem Unternehmen, sei es durch Forken eines bestehenden oder durch eigenes Schreiben, kann entmutigend sein. Aber für Design- und Engineering-Teams, die die Konsistenz zwischen Projekten wahren wollen, sind die Vorteile zu zahlreich, um sie zu ignorieren. Durch die Nutzung vordefinierter Muster erhalten Sie Einheitlichkeit in Optik und Code, schnellere HTML-Erstellung, weniger Fehler, weniger CSS-Bloat und es ermöglicht Produkt-Designern, weniger Zeit mit Spezifikationen und mehr Zeit mit den größeren Herausforderungen der Benutzererfahrung und Informationsarchitektur zu verbringen.