Skalierbare Projekte: CSS Methoden

09.02.2021

Der Versuch, CSS in großen Projekten zu strukturieren gerät spätestens nach dem ersten Release durcheinander. Man möchte verhindern, generelle Styles zu überschreiben und baut sich zur Vorsicht lieber ein neues Klassen-Konstrukt auf. Ein weiteres Problem: inkonsequente Umsetzung. Ein neuer Entwickler kommt zum Projekt hinzu und erhält keine Einweisung in die am Anfang festgelegten Richtlinien oder die festgelegten Richtlinien werden nicht umgesetzt und beobachtet. 

Die Folge: Es entsteht unstrukturierter Code, der nur noch nach Top-Down Ansatz eines Browser-Debuggers verstanden wird.

Oft wird dann ein !important als letzte Chance gesehen, seine Anpassungen dem Style aufzuzwingen. Dabei entsteht viel „dead code“ Code, der nicht gebraucht wird. Die CSS-Datei explodiert.

Schaut man auf die Entwicklung des CSS-Ökosystems in den letzten Jahren, merkt man, dass sich einiges getan hat. War vor einigen Jahren noch Bootstrap die Grundlage des Stylings für die meisten Projekte, so hat man heute viele verschiedene Möglichkeiten ein Projekt aufzusetzen. Dabei können unterschiedlichste Ansätze kombiniert werden. Eine noch größere Vielfalt entsteht.

In letzter Zeit haben sich allerdings zwei Ansätze herauskristallisiert. Einmal die komponentenbasierte Strukturierung und einmal das atomare Zerlegen in Klassen mit nur einer CSS-Eigenschaften. Dies spiegelt sich auch bei einer Umfrage „State of CSS 2020“ wider. Die Methoden BEM (komponentenbasiert) und Atomic CSS (atomar) genießen eine hohe Aufmerksamkeit.

Doch welcher Ansatz ist für große Projekte eine gute Wahl? Wie sollte die Architektur ausschauen? Kann man damit eine übersichtliche Strukturierung im späteren Prozess beibehalten?

BEM

Komponentenbasierte Architektur

Aufbau von BEM

BEM ist mittlerweile sehr bekannt unter Frontend-Entwicklern. Es ist eine Methode seine CSS-Sheets zu strukturieren und wiederverwendbare Blöcke aufzubauen. Dabei werden Elemente auf einer Webseite in Blöcke aufgeteilt, die Elemente und Modifier besitzen können. Der Scope der CSS-Definitionen wird dadurch auf diese Komponente begrenzt und die kaskadierenden Auswirkungen von CSS eingeschränkt. Es greifen kaum bis keine anderen CSS-Definitionen außerhalb dieses Scopes auf die Kompetente zu.

Die Wiederverwendbarkeit ist dabei ein großer Vorteil. Macht man es richtig, können einzelne Module einfach in andere Projekte übertragen werden, ohne größeren Aufwand. Zusätzlich hat diese Methode eine geringe Spezifität. D.h. bei speziellen Anforderungen an das Modul können Styles einfach überschrieben werden.

Oft ist es jedoch schwierig, vor allem am Anfang, alles in solche Komponenten aufzuteilen. Ist zum Beispiel in einem Card-Element eine Headline mit einer Subheadline schon eine Komponente, nur weil das öfter im Projekt vorkommt? Oder bleibt es ein Element der Card-Komponente?

Des Weiteren stößt man oft auf Schwierigkeiten im späteren Projekt, wenn es zu Änderungen an Stil und Markup der Komponente kommt. Man definiert entweder einen weiteren Stil der Komponente oder dupliziert diese sogar mit angepasstem Stil. Es entsteht viel doppelter Code und toter Code, der keine Auswirkungen mehr auf das Styling hat. Auch die Nutzung von sich wiederholenden Stilen ist nicht genau definiert. Man versucht dies mit Hilfe von Mixins zu lösen oder man dupliziert einfach die entsprechenden Eigenschaften.

Atomic CSS (ACSS)

Atomare Architektur

1
2
// CSS Deklaration
.Mt\(20px\) { margin-top: 20px}
1
2
<!-- HTML -->
<article class='Mt(20px)'></article>

Atomic CSS , auch ACSS, basiert im Prinzip darauf, für jede sich wiederholende CSS-Deklaration eine eigene Klasse zu definieren. So erhält man einen Abstand nach oben zum Beispiel mit der Klasse .Mt(20px)

Diese Methode wird bereits in aufstrebenden Frameworks wie Tailwind.css verwendet. Auch Facebook hat bei seinem Redesign auf Atomic CSS gebaut und dadurch unter andrem eine viel effizientere Struktur erschaffen, die eine 80% kleinere CSS-Datei am Ende ausspuckt im Vergleich zu der vorherigen Entwicklung.

Schaut man auf die Facebook-Seite einmal genauer auf ein div-Element und die jeweiligen Style-Deklarationen der einzelnen Klassen, wird das Prinzip etwas klarer. Jede Klasse hat genau eine Style-Deklaration. Durch diese Methode werden keine CSS-Nachkommen-Selektoren mehr verwendet, wodurch man anhand des HTML-Elements genau weiß, welche Styles an der Stelle greifen. Ein großer Vorteil, da man bei Styleanpassungen immer genau weiß, dass es keine Auswirkungen an einer anderen Stelle geben wird. 

Ein Nachteil an Atomic CSS ist, dass es die komplette Art und Weise wie man bisher CSS aufgebaut hat ändert. Es ist eine große Umstellung, die vielleicht am Anfang etwas schmerzt. Man verknüpft HTML und CSS mehr miteinander, wobei man doch jahrelang gelernt hat, diese strikt zu trennen. Zusätzlich bläht das HTML-Dokument stark auf und wird sehr unleserlich. Hier ein Beispiel:

1
2
<!-- HTML -->
<div class='Bgc(#555555) C(#fff) P(20px) Mt(20px) Blw(5px) Blc(#000) W(50%) H(50%)'>Beispiel</div>

Es wird klar, dass beide Ansätze sowohl Vor- als auch Nachteile mit sich bringen. Aber wie wäre es mit einer Kombination aus den beiden Methoden? Genau dieser Ansatz wird bei Cube CSS realisiert. Sie ist bei der CSS-Umfrage ein neuer Part der Aufstellung und hat bereits das Interesse von einigen Frontendlern geweckt.

© https://cube.fyi/ Cube CSS Logo

Cube CSS

Atomare und komponentenbasierte Architektur

Cube CSS ist ein neuer Ansatz, der die beiden Methoden ACSS und BEM vereint. Der Kern dieser Methode ist, die meisten Definitionen bereits mit globalen Styles und High-Level Styles einzubinden. D.h. bevor man eine Komponente erstellt, werden erst alle äußeren Einwirkungen definiert. Farben, Schriften, Kompositionen sind bereits definiert. Hier ein kleiner einblick in die Bedeutung von Cube:

Um in der HTML Datei eine leicht lesbare und konsistente Struktur herzustellen, werden die einzelne Klassen in Gruppen zusammengefasst. Dabei können auch statt der eckigen Klammern andere Zeichen zur Gruppierung verwendet werden, wichtig ist, man gruppiert und hält die Reihenfolge ein. Das verschafft eine leichte Lesbarkeit der HTML.

1
2
3
4
5
<!-- Beispiel mit eckigen Klammern -->
<attribute class=“[card] [section box] [bg-base color-primary]“>

<!-- Beispiel mit senkrechtem Strich  -->
<attribute class=“card | section box | bg-base color-primary>

Cube CSS erweitert die allgemeine CSS-Sprache. Es versucht nicht die Sprache neu zu entwickeln oder umzukrempeln, wie es teilweise bei BEM und ACSS den Anschein hat. Es nimmt die Fähigkeiten, wie die kaskadierende Eigenschaft von CSS, auf und versucht das bestmögliche dabei herauszuholen. Bei BEM und ACSS wird dies teilweise unterdrückt.

Zusammengefasst

Zusammengefasst ist eine solide Architektur das A und O für skalierbare Cascading Style Sheets. Dabei ist es wichtig, dass alle Entwickler in einem Projekt an einem Strang ziehen und die vordefinierten festgelegten Methoden und Regeln berücksichtigen und einhalten. Alle Methoden haben das Potenzial, eine gute Skalierbarkeit zu gewährleisten. Mit Cube CSS werden allerdings viele Vorteile vereint. Es wird viel Code durch die globalen und kompositionellen Definitionen gespart. Farben und Schriften können tokenbasiert gesetzt und verwendet werden und die HTML-Struktur bleibt übersichtlich. Anpassungen bei einem späteren Projektstand sind bei Einhaltung der Methode simpel umzusetzen.

Nadine Krietenbrink

Nadine Krietenbrink

Über den Autor

Nadine ist Spezialistin für User Experience Design und Frontend-Entwicklung. Bei actidoo beschäftigt sie sich mit der Erstellung komplexer Prototypen und der Umsetzung von Webapplikationen. Mit ihrer Leidenschaft für qualitative UIs möchte sie dem Endnutzer nicht nur eine Freude bereiten, sondern ihm auch mit einer intuitiven Bedienung die Nutzung erleichtern.