28. November 2018 – Development

«BEMIT» –

Skalierbare und wartbare (S)CSS-Architektur mit mehr Transparenz

 

In der Softwareentwicklung konzentrieren wir uns im Allgemeinen auf Dinge wie Architekturen, Namenskonventionen, Methodologien, Skalierbarkeit. Komplexität wird mittels Objektorientierung und Modularisierung reduziert und Logik wird in einzelne Komponenten aufgeteilt. Für das Styling im Frontend kommen meist «Cascading Style Sheets» (CSS) zum Einsatz, weil es einfach ist, diese zu schreiben. Das ist jedoch nicht zwingend!

 

 

 

Die Projekte werden komplexer, Entwicklungsteams immer grösser. Als Programmierer stelle ich oft fest, dass wir viel Zeit damit verbringen, vorhandenen Code zu interpretieren, zu pflegen und umzuarbeiten, statt neuen Code zu schreiben. Gerade im Bereich CSS werden altbekannte Paradigmen wie «don’t repeat yourself» und «clean code» gerne vernachlässigt.

Wie mache ich mein CSS skalierbar und wartbar?

Das Problem

Wartbaren und überschaubaren CSS-Code zu schreiben ist nicht so einfach, wie es auf den ersten Blick scheint. Geht es zudem um Wiederverwendbarkeit und Skalierbarkeit, sind die Anforderungen hoch. Unstrukturierter und schlechter CSS-Code kann schnell zum Albtraum für jeden Entwickler werden. Anpassungen am Code können schnell unerwünschte Nebeneffekte durch Vererbung der Styles (cascading style sheets) nach sich ziehen.

«BEMIT» hat eine Antwort

Der Begriff setzt sich zusammen aus der BEM-Notation und der «Inverted Triangle CSS Architecture» (ITCSS).

BEM-Notation

BEM (Block, Element, Modifier) ist eine Methodologie mit definierter Syntax, wie Klassen in HTML vergeben und diese als Selektoren in CSS genutzt werden können. BEM ist aber keine genau standardisierte Norm, sondern vielmehr eine «Art zu denken».

Das HTML-Markup wird dabei in Komponenten aufgeteilt, wobei jede der Komponenten in drei Gruppen strukturiert wird:

  • Block: das «root» als eigenständige Komponente, mit eigener Semantik.
  • Element: Bestandteil des Blocks, ohne eigenständige Bedeutung.
  • Modifier: eine Variante oder Erweiterung des Blocks.

BEM-Syntax

HTML

CSS (SASS-Schreibweise)

Grundregeln
 

  • Alle(!) CSS-Selektoren bestehen aus lediglich einer Klasse.
  • Keine #IDs als Selektoren.
  • Keine verschachtelten Selektoren (ul > li > ul > li > a), was nicht zu verwechseln ist mit der SASS-Schreibweise.
  • Keine Markup/DOM-Abbildung im CSS.
  • Kein Einsatz von «!important».
  • Selektoren so unspezifisch wie möglich, so spezifisch wie nötig.
  • Keine HTML-Tag-Selektoren (nav, button, body usw.).

Die wichtigsten Vorteile
 

  • Einfachere Wartung und Erweiterung von Styles
  • Keine Probleme durch Vererbungen
  • Vermeidung unerwünschter Nebeneffekte bei Stilanpassungen
  • Aufbau einer Art «Objektorientierung» in CSS
  • Modularisierte und übersichtliche (S)CSS-Files
  • Ändern sich im HTML die Hierarchien von Elementen, bleibt der CSS-Code dank eindeutigen Klassen-Selektoren trotzdem gültig

ITCSS (Inverted Triangle CSS Architecture)

ITCSS ist ein Designkonzept (Architektur-Modell) für die Organisation von CSS in Softwareprojekten. Dabei verfolgt ITCSS ähnliche Ansätze wie SMACSS oder OOCSS. Entwickelt wurde das Ganze von Harry Roberts (csswizardry.com). Primär geht es darum, Kaskadierungen und Spezifikationen von CSS unter Verwendung von verschiedenen Namespaces in sogenannte «Layer» zu unterteilen. Wiederverwendbarkeit und Skalierbarkeit stehen im Vordergrund.

Es steht dem Entwickler dabei frei, mit «pure» CSS zu arbeiten oder unter Einsatz eines CSS-Preprocessors z.B. SASS zu verwenden. An dieser Stelle möchte ich anmerken, dass wir nur noch mit SASS arbeiten, was einige Vorteile mit sich bringt.

Das «umgekehrte Dreieck» repräsentiert dabei:

  • CSS Styles in Abhängigkeit zu CSS-Selektoren im DOM
  • Von sehr generischen Styles (gesamter DOM, weit verbreitet) bis zu expliziten Styles (sehr lokal)
  • Von wenig spezifischen bis zu sehr spezifischen Selektoren

ITCSS – Layers
 

Settings

Beinhaltet alle projektweiten «SASS»-Variablen, die in allen Codefiles verwendet werden können. (Layer entfällt ohne CSS-Preprocessor.)

Beispiele:

  • Farben
  • Spacings

Tools

Dieser Layer ist für «mixins» und andere Funktionen gedacht, die ganz global zum Einsatz kommen sollen. (Layer entfällt ohne CSS-Preprocessor).

Beispiele:

  • Mixins für Fonts
  • Animationen

Generic

Der erste Layer, in welchem reines CSS zum Einsatz kommt.

Wenig spezifische Styles, welche über einen sehr breiten DOM-Bereich greifen, werden hier abgelegt.

Beispiele:

  • Box-sizing
  • Normalize

Elements

Dies ist der letzte Layer, in dem wir Type-Selektoren verwenden(!).

Hier werden die klassenlosen HTML-Tags (Elemente) direkt gestylt (sehr generisch).

Beispiele:

  • Headings (h1, h2 ... )
  • Lists (ul, li)

Objects «o»

An dieser Stelle kommen zum ersten Mal CSS-Klassen zum Einsatz. Objekte sind in diesem Fall kleine und wiederverwendbare Einheiten von Code, welche im gesamten UI an verschiedenen Stellen gleichzeitig vorkommen können, nicht nur im aktuellen Kontext, der betrachtet wird. Anpassungen an Objektklassen können an verschiedenen Stellen auf der Seite Veränderungen nach sich ziehen.

Beispiele:

  • Wrapper
  • Grid (layout)
  • Buttons
  • Inputs

Components «c»

In diesem Layer werden konkret ausgestaltete Implementationen von UI-Bausteinen abgelegt. Also schon sehr spezifisch. Alle Änderungen der Styles sollten im aktuellen Kontext der Komponente wirken, da eine Komponente im Normalfall pro Seite nur einmal im Einsatz ist.

Beispiele:

  • Navigation
  • Footer
  • Header

Utilities «u»

Hier werden Helferklassen abgelegt, welche eine hochspezifische Aufgabe zu erledigen haben. Im Normalfall genau eine. «Do one thing and do it well.»

Vorangehende Styles aus dem hierarchischen «triangle» werden übersteuert und es ist ausnahmsweise sogar erlaubt, ein «!important» einzusetzen. Sie können über den gesamten UI-Bereich explizit verwendet werden.

Beispiele:

  • Alignment
  • Displaying
  • Positioning

Resultat

Mehr Semantik und Transparenz in unserem Code

Am Ende erhalten wir durch diese Art der Strukturierung unseres Codes auch deutlich mehr Semantik in unserem HTML-Markup. Es ist schnell ersichtlich, ob es sich bei einer CSS-Klasse um eine Komponente, ein Objekt oder Helferklassen handelt, dank Namespace-Präfix. Dabei ist gleichzeitig auch klar, in welchem Layer die CSS-Klasse letztendlich definiert ist und wo der Entwickler diese suchen muss.

Fazit

CSS in einem Projekt vernünftig zu orchestrieren, ist keineswegs einfach. Die BEM-Notation in Kombination mit dem «Inverted Triangle»-Konzept ist ein geniales Designpattern, um Stylesheets in Webprojekten zu strukturieren. Zugegeben, es war am Anfang etwas gewöhnungsbedürftig, im Sinne von «BEM» so viele lange Klassennamen im HTML zu definieren, doch es macht am Ende eben alles Sinn. Für uns sind diese Methoden nicht mehr wegzudenken und wir haben diese in unseren Entwicklungsprozess fix integriert und als Standard definiert. Im Zusammenspiel mit SASS als CSS-Preprocessor ist das ganze Konzept sehr mächtig und effizient. Wir sparen am Ende viel Zeit, Geld und vor allem auch Nerven.

#theCodingLove

 

Blog-Artikel teilen:

 

Möchten Sie regelmässig über neue Blog-Beiträge informiert werden?

 

 

0 Kommentare

Teilen Sie uns Ihre Meinung mit