Modulare Webentwicklung

Modulare Webentwicklung
Modulare Webentwicklung
Buy on Leanpub

Inhaltsverzeichnis

1. Vorgeplänkel

Seit einigen Jahren halte ich immer wieder Vorträge und gebe Schulungen, um meine Ideen modularer Webentwicklung zu verbreiten. So einmalig und besonders sind diese Ideen gar nicht. Insbesondere die Modularisierung des HTML dürfte heute implizit gang und gäbe sein. Ausser bei den meisten Wordpress-Projekten, da dieses CMS seitenbasiert funktioniert. Doch es besteht ein Unterschied zwischen der Modularisierung durch Templates innerhalb eines CMS und dem dazugehörigen modularen CSS. Während das HTML der Webseiten üblicherweise in kleine Schnipsel (Templates) aufgeteilt werden, ist das CSS meist nicht so optimal geschrieben.

Auf meinen Heimreisen begann ich, das eben Gelehrte in Worte zu fassen. Dabei habe ich über die Jahre an mir selber eine Veränderung in der Haltung zum Thema festgestellt. Diese Webseite / dieses Büchlein ist nun die Quintessenz meiner Schulungen und Überlegungen. Gut möglich, dass der Inhalt in Zukunft erweitert wird, denn das Thema ist in Bewegung. Angetrieben von Styleguides und Pattern Libraries beschäftigen sich heute immer mehr Entwickler mit vernünftigem Code für CSS und HTML.

Für das bessere Verständnis der Inhalte ist es unerlässlich, zumindest zwei Grundprinzipien von CSS verstanden zu haben: die Kaskade und die Spezifität.

Die Kaskade

Das “C” in “CSS” steht für “Cascading”, also die Kaskade. “Wer zuletzt kommt, malt zuerst” kann man das Prinzip der Kaskade zusammenfassen. Eine Regel überschreibt eine gleichwertige Regel, wenn sie nach dieser im Code kommt. Nehmen wir dieses simple Beispiel:

 1 p {
 2 	color: red;
 3 	margin-bottom: 10px;
 4 }
 5 
 6 /* Hier kommen einige Zeilen CSS-Code. */
 7 
 8 p {
 9 color: black;
10 }

Da in der zweiten Regel eine Farbe definiert wurde, überschreibt sie die Farbe der ersten Regel. Alle Absätze werden also nun mit schwarzem Text formatiert. Das margin-bottom bleibt unangetastet, denn es wurde in der zweiten Regel nicht erwähnt. Diese Technik ist ein wichtiger und integraler Bestandteil von CSS. Die Kaskade kann nur durch eine unterschiedliche Spezifität ausgehebelt werden.

Die Spezifität

Die Spezifität ist das zweite wichtige Grundprinzip von CSS. Sie ist die Antwort auf die Frage, wie allgemein oder wie spezifisch eine Regel ist. Die oben gesehene Regel für einen Absatz ist sehr allgemein:

1 p {
2 	color: black;
3 }

Damit werden alle Absätze angesprochen. Weniger allgemein ist diese Regel:

1 article p {
2 	color: blue;
3 }

Diese Regel gilt nur für alle Absätze, die sich in einem article-Element befinden. Die Regel wendet sich also spezifisch an Absätze in einem bestimmten Kontext. Gleiches kann man mit Klassen machen oder einer Kombination Klassen und Elementen:

1 .box {
2     margin: 10px;
3 }
4 
5 article.box {
6     margin: 20px;
7 }

Klassen können an jedes Element gehängt werden. Deshalb ist die zweite Regel spezifischer als die erste, denn sie konkretisiert die Anwendung der Klasse: die Klasse .box wird an einem article-Element genutzt, nicht an einem div oder einem anderen Element.

Je spezifischer eine Regel ist, desto höher ist ihr Wert, der in Zahlen ausgedrückt werden kann. Und durch diese Spezifität wird das Prinzip der Kaskade durchbrochen:

1 article p {
2 	color: blue;
3 }
4 
5 p {
6 	color: black;
7 }

Obwohl in der zweiten Regel alle Absätze eine schwarze Schrift bekommen, bleiben alle Absätze innerhalb eines article-Elements blau. Die dazugehörige Regel ist spezifischer, weshalb die Kaskade nicht zieht.

Richtiger Umgang mit diesen Prinzipien

Kaskade und Spezifität werden uns immer wieder begegnen. Sie sind der Schlüssel für effiziente, wartbare und verständliche CSS-Dateien. Entwickler, die entweder diese Prinzipien nicht kennen oder sie nicht beherrschen, werden unglücklich mit der Arbeit an CSS-Dateien. Gerne wird dann der Vorwurf erhoben, CSS sei “kaputt”. Dem ist aber nicht so. Das Probelm ist nicht CSS, es ist unvollständiges Wissen der Entwickler über die Funktionsweise der Sprache. Dabei steht ganz oben die Erkenntnis, dass CSS keine Programmiersprache ist und sich deshab auch nicht deren Prinzipien und Denkmustern unterwerfen muss.

Es gibt drei Faktoren für schlecht wartbares CSS. Oft wird es von Entwicklern geschrieben, denen vertieftes CSS-Wissen fehlt.

Der erste Faktor ist die generell überspezifische Formulierung einer Regel, wie in diesen Beispielen:

 1 html.ng-scope body.ui-layout-container div#dialog.dia\
 2 log-frame section.dialog-frame-body section.content s\
 3 ection#dialogBody form#balanceOptionsForm.stform fiel\
 4 dset#morebalanceoptions ul li label { 
 5     /* .... */
 6 }
 7 
 8 html body div.project-body section.project-main #proj\
 9 ect-content .project-service_bar { 
10     /* .... */
11 }

Hier wird im Prinzip das DOM abgebildet. Das ist zum einen unnötig und zum anderen gilt diese Regel wahrscheinlich nur in diesem einen Projekt. Doch dazu später mehr.

Ein zweiter Faktor ist eine hohe Anzahl der !important-Zusätze in Regeln. In Einzelfällen kann ein !important zu rechtfertigen und zweckmässig sein. Doch spätestens bei 10 Stück in einem Stylesheet ist die Grenze des Sinnvollen erreicht. Ein !important wird gerne dann genutzt, wenn der betreffende Entwickler keinen Überblick (mehr) über die bisher genutzten Regeln hat. Das kann an einem unsortierten CSS, aber auch an mangelnder CSS-Kompetenz liegen. Ein !important ist eine schnelle und trügerische Lösung.

Und als Drittes: Am Ende des Stylesheets sammeln sich gerne im Laufe des Projektes wild durcheinander Regeln, die andere Regeln überschreiben sollen. Oft passiert dies durch eine höhere Spezifität, indem mehr DOM-Knoten vor die eigentliche Regel geschrieben werden (siehe Faktor 1). Gerne wird auch das eben erwähnte “!important” zu Hilfe genommen.

All dies wollen wir in Zukunft hinter uns lassen. Steigen wir also ein, in die modulare Webentwicklung!

2. Webseiten modular entwickeln

In allen Programmiersprachen gibt es Diskussionen darüber, wie man seine Applikation möglichst effizient und gut wartbar entwickelt. Die Diskussionsergebnisse fliessen in Entwicklungsparadigmen wie MVC (Model-View-Control) oder in Benamungsrichtlinien ein. Folgt man solchen Standards, ist es leichter, Code von anderen zu verstehen und zu übernehmen.

Im Bereich der Frontendentwicklung sind über die Jahre auch solche Standards entstanden, sie haben aber nicht die gleiche normative Kraft entfaltet. Das ist vor allem deshalb sehr bedauerlich, weil viele unterschiedliche Entwicklertypen für den Frontendcode verantwortlich sind. Speziell die Backendentwickler, die neben ihrer Hauptaufgabe auch Frontendcode schreiben müssen, wären sicherlich sehr dankbar für klare Richtlininen zur Formulierung guten Codes. Auch die Arbeit in Teams wird durch Regeln erleichtert. Sie gewährleisten einen vergleichbaren, für alle leichter verständlichen Output.

Es gibt nicht die eine Art, das Frontend zu entwickeln. Es gibt hingegen viele unterschiedliche Wege, HTML und CSS zu organisieren. Einige werde ich später skizzieren und meinen eigenen Weg dagegen halten. Doch bei aller Lust am Entwurf von Coderichtlinine sollte man immer die spezifischen Eigenheiten seines Projektes im Auge haben. Wenn es das Wissen der Teammitglieder erlaubt, sollten die Vorgaben flexibler sein, als bei Teams mit einem hohen Anteil an Entwicklern mit geringer Frontendkompetenz.

Eine Seite ist eine Ansammlung von Modulen

Eine Webseite setzt sich aus vielen unterschiedlichen Einzelteilen zusammen, die gängigsten sind Header, Footer und der immer anders angeordente Inhalt. Meist werden diese Einzelteile mittels eines CMS aus einzelnen Bausteinen kreiert. Wir gestalten und entwickeln im Grunde keine Seiten, sondern Systeme. Diese Systeme bestehen aus vielen einzelnen Elementen, die man Module nennen kann. Diese Module sind prinzipiell unabhängig voneinander, jedes ein eigenes kleines Universum. Gängige Module sind beispielsweise:

  • Navigationen
  • Linklisten in Seitenleisten oder im Footer
  • Teaserboxen - mit oder ohne Bild
  • Slider/Karussell
  • in einem Akkordeon organisierte Inhalte
  • in einem Tab-Interface organisierte Inhalte
  • eine eingebettete Landkarte

Für Backendentwickler ist dies sicherlich keine neue Erkenntnis, da sie im Normalfall die Einzelteile einer Webseite in diversen Templates realisieren und getrennt ablegen. Auch Frontendentwickler schreiben Seiten nicht in einem Rutsch durch, sondern nehmen sich die einzelnen Bestandteile (Module) nacheinander vor.

Nicht immer wird aber aus dieser Vorgehensweise die richtige Schlussfolgerung gezogen. Denn wenn wir schon die Webseiten schrittweise, modular erstellen, dann sollten diese einzelnen Module auch möglichst unabhängig voneinander existieren können. Das tun sie aber meist nicht. Über diese Diskrepanz soll es im Folgenden gehen.

Einzelne Module der Startseite der ZEIT markiert
Einzelne Module der Startseite der ZEIT markiert

Dieser Screenshot repräsentiert eine nicht mehr aktuelle Version von ZEIT.de.

Einzelne Module der Startseite der ZEIT markiert
Einzelne Module der Startseite der ZEIT markiert

Mitte 2017 ist dies die aktuelle Version von ZEIT.de.

Der Aufbau der 2012 redesignten Seite von Microsoft
Der Aufbau der 2012 redesignten Seite von Microsoft

Der Aufbau der 2012 redesignten Seite von Microsoft, Quelle: Artikel von Dave Rupert

Erst der Sinn, dann die Optik

Sie sollten sich immer wieder vor Augen halten, dass HTML die Basis aller Webseiten ist. CSS und JavaScript sind als die Erweiterungen azusehen. CSS ist für die hoffentlich attraktive Optik zuständig. JavaScript soll die Seite hingegen dynamisch machen. Das kann über das Hinzuladen von Inhalten passieren (AJAX) oder über Oberflächeneffekte (bspw. ein Akkordeon). Trotz aller schönen und dynamischen Optik beginnt jede Seite aber mit hoffentlich gutem, semantischem HTML. Webentwicklung ist ein Handwerk, keine Kunst. Semantisch armes HTML spricht Bände über die Fähigkeiten des Handwerkers. Bevor Sie also anfangen, die Gestaltung mit CSS umzusetzen, sollten Sie zuerst sinnvolles HTML erzeugen.

Mittlerweile haben Sie eine Fülle semantischer Elemente zur Verfügung. Sie sollten sie nutzen. Eine Webseite besteht aus mehr als nur DIV, P und SPAN. Erst nachdem Sie sich Gedanken über das korrekte HTML gemacht haben, sollten Sie sich mit CSS und JavaScript beschäftigen. Denken Sie bitte immer daran, welches HTML-Element dem Sinn nach genutzt werden sollte, nicht der Optik nach. Schliesslich besteht ein Teil der späteren Arbeit darin, die eigentlich gewohnte Optik von Elementen stark zu verändern. Bei Navigationen machen wir dies immer. Niemand sieht ihnen an, dass sie eigentlich Listen sind. Von der Optik können wir also nicht zwangsweise auf das HTML schliessen. Sie müssen sich schon mit den Inhalten beschäftigen.

Layout und Design

Unter Layout verstehe ich die Verteilung der Inhalte im Browserfenster, ihr horizontales und vertikales Arrangement. Hierfür werden normalerweise Grids oder Spalten genutzt. Design liegt dann vor, wenn Elementen innerhalb dieses Layouts eine konkrete Optik verpasst wird. Design ist also im Idealfall schön.

Das Layout ist unabhängig vom jeweiligen Design, das sich im Wesentlichen mit Farben, Größen und Abständen beschäftigt. Design ist grob gesagt die Dekoration. Layout kann sich auf die Webseite als Ganzes oder auf ein einzelnes Modul beziehen. So können bspw. die Inhalte eines Teasers vertikal oder horizontal angeordnet sein.

Grundsätzlich sollte die Platzierung des jeweiligen Moduls innerhalb des Layouts egal sein. Es sollte sich bei kleinem und großem Platz anpassen, unter Beibehaltung der eigenen Funktionalität. Module sollten also generell unabhängig vom Layout sein.

Ich empfehle dringend, auch beim Schreiben von HTML und CSS diese beide Ebenen zu trennen. Es sollte auf der einen Seite Klassen geben, die nur das Layoutgerüst konstruieren und auf der anderen Seite Klassen, die sich um das Design der Inhalte kümmern. Das Layout sollte zudem aus eigenständigen Elementen bestehen. In diese werden dann die Module als eigenständige semantische Konstrukte platziert. Ein Beispiel für ein Layoutgerüst (ohne Inhalte):

1 <div class="ym-grid">
2 	<div class="ym-g60 ym-gl">
3 		<!-- Hier kommt das Inhaltsmodul hin!  -->
4 	</div>
5 	<div class="ym-g40 ym-gr">
6 		<!-- Hier kommt das Inhaltsmodul hin!  -->
7 	</div>
8 </div>

Wir diskutieren hierbei nicht über die korrekte Verwendung von Klassen. Mir ist nur wichtig zu zeigen, dass mit dieser einfachen Struktur und diesen paar Klassen ein Grid erzeugt wurde. In diesem Falle ist der erste Container 60% breit und der zweite 40%. Das Beispiel wurde vom CSS-Framework YAML entlehnt.

Das Gridmodul existiert unabhängig von den Inhaltsmodulen und kann an unterschiedlichen Stellen wiederverwendet werden. Die Inhaltsmodule passen sich dem ihnen von den Layoutmodulen zur Verfügung gestellten Platz an. Dadurch haben wir eine Trennung von Seitenlayout und Inhalten erreicht. Diesen benötigen wir, damit die Inhaltsmodule transportabel sind. Ein Teasermodul kann an der einen Stelle beispielsweise zwei Drittel, an der anderen nur ein Drittel des Platzes wegnehmen. Würden wir dem Teasermodul direkt Layouteigenschaften mitgeben (bspw. <code>float</code> und Breite), so wäre das Modul nicht mehr einfach zwischen Seitentypen oder gar Projekten transportabel. Und das wäre in meinen Augen eine unnötige Einschränkung.

Der neue Blick auf das CSS

Seit ein paar Jahren gibt es vermehrt Artikel und Bücher, die sich mit der Organisation und der Nomenklatur von Webseitenstrukturen und ihrer Gestaltung durch CSS widmen. Mir gefällt dieser Blick auf unsere Methodik, denn ich habe während meiner gesamten Berufslaufbahn immer wieder meine Arbeitsweise hinterfragt. Mein Bestreben war es immer, das nächste Projekt effizienter zu erledigen.

Über die Jahre habe ich meine Arbeitsweise mehrfach geändert. Dazu trugen technische Veränderungen genauso bei, wie Anregungen von aussen. Der sogenannte “objektorientierte Ansatz” - präsent und bekannt in den Projekten OOCSS, SMACSS und BEM - hat auf lange Sicht den größten Einfluss ausgeübt. Einzelne Aspekte der Ansätze hatte ich schon in meinen Projekten, bevor ich von OOCSS und Konsorten überhaupt Kenntnis hatte. Allerdings fehlte es meiner Arbeit an der letzten Konsequenz. Vor allem SMACSS empfand ich als besonders hilfreich.

Die objektorientierten Ansätze wenden den Blick von der reinen Gestaltung und der Erzeugung von Effekten ab. Ihnen geht es nicht um das “was”, sondern um das “wie”. Sie befördern den systematischen und durchdachten Umgang mit Klassen. Dadurch wird Teamarbeit erleichtert, ebenso die Übergabe an andere Entwickler. Und auch man selber sollte durch eine konsistente Systematik leichter in ältere eigene Projekte wieder reinfinden können.

In meinen Augen liefern alle drei Ansätze interessante Aspekte. Ich empfehle nicht, einem dieser Ansätze sklavisch zu folgen. Aber ich empfehle, sich anhand dieser Ansätze - und meiner hier folgenden Ausführungen - Gedanken über die eigene Arbeitsweise und den Aufbau der eigenen Projekte zu machen.

Das Ziel: Modulbaukasten

Wenn wir unsere Module so schreiben, dass sie für sich stehen und im sinnvollen Rahmen beliebig auf einer Seite platziert werden können, dann können wir sie auch auf einer Übersichtsseite sammeln. Es entstünde so etwas Ähnliches wie das berühmte “Bootstrap”: ein eigenes Bootstrap, das auf eigenem Code aufbaut. Jeder Frontendentwickler und vor allem jede Agentur kann sich einen solchen Modulbaukasten (oder auch Framework) aus vergangenen Projekten zusammenstellen.

Bootstrap ist nur deshalb so beliebt, weil es eine grosse Menge immer wieder nachgefragter Module zur Verfügung stellt, die Anwender einfach nur per “copy & paste” in eine Seite fallen lassen müssen, um eine funktionierende Seite zu erhalten, die sogar ein halbwegs ansprechendes Design als Ausgangslage mitbringt.

Jede Agentur hat allerdings das Potential, sich ein eigenes Bootstrap aufzubauen, um sich daraus zu bedienen. Dadurch kann man in einem ersten Schritt sehr viel einfacher und schneller mit Rapid Prototyping arbeiten.

Ausserdem muss man nicht für jedes Projekt die immer wieder gleichen Elemente von neuem schreiben. Man kopiert sich einfach schon erfolgreich getesteten Code und passt ihn an. Und je weniger Abhängigkeiten es zwischen den einzelnen Modulen und allgemeingültigem CSS gibt, desto besser. Es bleibt jedem selbst überlassen, wieviel eigener Code mit wieviel Fremdcode kombiniert wird.

Ein Modulbaukasten erleichtert die Dokumentation der Module, erleichtert den Austausch mit Kunden und Designern. Es entsteht eine Fundgrube für Module, die in zukünftigen Projekten genutzt werden können. Dabei sollten Sie immer im Hinterkopf behalten, dass das Design eines Moduls sich relativ leicht ändern/anpassen lässt. Eine horizontale Navigation lässt sich mit nur wenigen Zeilen CSS optisch stark modifizieren. Finden Sie deshalb eine neutrale Darstellung für Ihre Module. Arbeiten Sie mit Grautönen und neutralen Bildern und Logos.

So entstehen schnell eigene Klickdummys, deren Einzelteile immer wieder weiterverwendbar sind.

Die Idee des Modulbaukastens wird heute für die Abarbeitung einzelner Projekte als Living Styleguide oder Pattern Library beworben. Und was für ein einzelnes Projekt gilt, kann auch für viele gelten. Sammeln Sie Module/Patterns, so sparen Sie sich unnötige Arbeit.

3. Mit CSS gestalten

Mit CSS gestalten wir HTML-Seiten. Es stehen uns hierbei mehrere unterschiedliche Möglichkeiten offen und drei unterschiedliche Wege, CSS auf HTML einwirken zu lassen.

Wir können CSS-Regeln über Elemente, Klassen, IDs oder spezielle Selektoren (und jede beliebige Kombination daraus) auf HTML-Elemente einwirken lassen. Wir können das CSS in den Kopf der HTML-Seite schreiben, direkt an das Element oder in ein externes Stylesheet. Wir können CSS sogar über JavaScript schreiben, auch hier über die drei eben beschriebenen Wege.

Alle diese Möglichkeiten und Wege sind primär wertfrei zu betrachten. Sie sind weder falsch noch richtig. Leider wollen uns immer wieder Entwickler einreden, es gäbe gute und schlechte Arten, CSS zu schreiben und zu implementieren. Da die Standards viele Wege offen lassen, geht ein einfaches “Gut-Böse”-Schema an der Realität vorbei. Wir sollten eher von praktischen oder unpraktischen Methoden sprechen. Das sind jedoch situationsabhängige Eigenschaften. Man kann sie nicht abstrahieren und allgemeingültig machen.

Die berühmten “Best Practices”

Welchen Weg und welche Methode wir auch wählen, wir haben es immer mit Vor- und Nachteilen zu tun. Im Allgemeinen ist es am Sinnvollsten, Styles in ein externes Stylesheet zu schreiben. So muss man nur eine CSS-Datei pflegen und kann diese mit unendlich vielen HTML-Dateien verbinden.

Aber nehmen wir einmal an, in einem Modul - beispielsweise einer Teaserbox - müssen immer wieder individuelle Hintergrundbilder eingebunden werden. Diese Hintergrundbilder können nicht im Vorhinein definiert werden. Es handelt sich hierbei um eine redaktionelle Arbeit. Doch niemand möchte einem Redakteur Zugriff auf das CSS geben. Also bietet sich die Arbeit mit einem Inline-Style an. Diese Ausnahme von der Regel ist sinnvoll. Ein pauschales Verbot der Nutzung von Inline-Styles wäre demnach kontraproduktiv.

Yahoo schreibt auf der jeweiligen Startseite große Teile des CSS direkt in den Head, weil die Styles so schneller geladen sind, als über eine externe Datei. Vor einigen Jahren schrieben sie sogar alle CSS-Regeln auf der Startseite in den Head - auch aus Performancegründen. Denn sie hatten durch Analysen festgestellt, dass die meisten Besucher mit geleertem Cache vorbeikamen. Der positive Effekt externer CSS-Dateien war also dahin. Die Vermeidung eines Requests trug offenbar zum schnellen Laden der Startseite bei. Heute spricht man in diesem Zusammenhang von “Critical CSS” und “Above the fold”.

Das mag uns auf den ersten Blick nicht gefallen, es mag sich falsch anfühlen. Aber es zeigt, dass wir ein Problem mit “Best Practices” haben. Denn was die meisten Entwickler als ebensolche verstehen, mag in Einzelfällen problematisch sein. In Einzelfällen mögen “Bad Practices” die “Best Practices” sein. Wichtig ist, dass wir uns ernsthaft mit unseren Rahmenbedingungen auseinandersetzen und über das effektive Handling in unserem Projekt nachdenken.

Aufpassen bei Verboten

Wie wir später sehen werden, arbeiten Coderichtlinien gerne mit Verboten. Die Verbote treffen dabei auch Techniken, die sich bewusst im CSS-Sprachschatz befinden. Die einseitige Fokussierung auf Klassen und die Negierung anderer Selektoren erschwert m.E. die Arbeit unnötig. Einen ersten Absatz kann man prima mit :first-child selektieren und dann gestalten. Dafür muss weder ein Redakteur im Editor eine Klasse zuweisen noch eine besondere Logik im Backend programmiert werden, um eben jenem ersten Absatz eine spezielle Klasse zuzuweisen.

Auch die Markierung besonderer Linkarten wie ein verlinktes PDF, Word-Dokument oder der Verweis auf eine andere Domain können mit einfachen CSS-Attributselektoren passend gestaltet werden. Weder ein Redakteur, noch ein Backend-Entwickler werden benötigt.

Deshalb plädiere ich dafür, Vorsicht bei Verboten walten zu lassen. Es kann sein, dass man sich durch deren Befolgung unnötige Probleme ins Projekt holt.

Man muss diese Verbote aus dem Kontext heraus verstehen. Alle diese objektorientierten Ansätze wurden unter dem Eindruck großer Teams erdacht. In diesen Teams waren zudem die Frontend-Kenntnisse nicht gleichmässig gut verteilt. Sollten Sie also in einem Team mit Entwicklern arbeiten, die kaum Ahnung von CSS haben, dann sind restriktive Regeln eine große Hilfe. Sie geben Orientierung und Sicherheit. Sollten Sie aber mit richtig guten Frontendentwicklern arbeiten, verschlechtern Sie evtl. durch allzu große Restriktionen nur das Arbeitsklima.

Wenn der Standard Ihnen Techniken an die Hand gibt, müssen Sie sie nicht nutzen. Sie sollten sich aber auch bewusst sein, dass diese Techniken nicht per se falsch sein können. Es kommt auf den Kontext und den konkreten Anwendungsfall an.

4. Volle Kontrolle über den Code

Haben Sie volle Kontrolle über den Code, bspw. weil Sie Ihre eigene Webseite coden - am Besten ohne ein CMS -, dann können Sie in der Tat auch im Sinne der Codemethodiken aus dem vollen Schöpfen. Sie können dann jeder Überschrift, jedem Link eine Klasse geben und SPAN-Elemente verteilen, wenn es Ihnen wichtig und ratsam erscheint.

Aber mal ehrlich: wann können Sie dies von einem Projekt sagen? Und handelt es sich dabei um ein wichtiges, lukratives Projekt?

Hinzu kommt, dass es auch 2017 noch immer Contentmanagementsysteme gibt, die eigenständig Code schreiben. Mal werden DIV-Container ohne tieferen Sinn erzeugt, mal jedem noch so dürftigen Element eine ID gegeben. Auch CMS-Plugins können Code erzeugen, den Sie oft nicht beeinflussen können. Sehr oft haben Sie also keinen hundertprozentig kontrollierbaren Frontendcode vor sich. Darauf müssen Sie in Ihrem CSS reagieren.

Inhaltspflege kommt von Redakteuren

Der Normalfall für uns Webworker dürfte sein, dass die Pflege des Inhalts von Redakteuren kommt. Diese haben meist keine HTML-Kenntnisse und sollen sich ganz auf ihre Inhalte konzentrieren. Von Redakteuren erfasste Texte sollten also möglichst nicht mit optionalen Elementen und Klassen versehen werden müssen. Die Redakteure sollten sich auf Absätze und Listen (evtl. noch Tabellen) konzentrieren.

Gehen Sie gedanklich immer von einer einzigen Editorinstanz aus, sodass es schwer bis unmöglich wird, einzelnen Absätzen spezielle Klassen mitzugeben.

Das ist ein wichtiges Detail. Denn schliesslich müssen wir im Frontend dafür sorgen, dass die Redakteure ihre Inhalte auch optisch mit Variationen versehen können. Wenn sie aber bei der Erstellung einer Liste oder der Erfassung eines Absatzes keine Klasse(n) hinzufügen können, müssen wir nicht nur innerhalb unseres CMS einen praktikablen Weg finden. Wir müssen auch innerhalb unseres CSS die korrekten Selektoren finden, die uns dies ermöglichen.

Ausnahmen sollten nicht die Regel werden

Vor ein paar Jahren schulte ich eine Gruppe von Redakteurinnen. Nach dem avisierten Relaunch sollten sie nicht mehr wie bisher ihre Texte individuell gestalten dürfen. Ein Standarddesign sollte sie dazu in die Lage versetzen, sich mehr auf die Inhalte zu konzentrieren. Natürlich sollten auch diverse optische Auswüchse beseitigt werden. Denn nicht jeder, der einen CMS-Editor und dessen Buttons bedienen kann, hat auch ein Auge für Design.

Es war eine harte Diskussion, den Redakteurinnen klarzumachen, dass sie in Zukunft nicht mehr machen könnten, was sie gerade wollten. Viele Kunden empfinden die Leistungen eines Designs geradezu als unverschämte Beschränkung.

Diese Beschränkung ist aber wichtig. Und sie ermöglicht uns erst, vernünftige Styles zu schreiben, die eine einheitliche Gestaltung realisieren. Ich sehe die Einschränkungen durch Layoutregeln zudem nicht negativ. Ich empfinde sie als sehr hilfreich, denn da sie meine Handlungsoptionen tatsächlich begrenzen, ermöglichen sie mir die Fokussierung auf die Inhalte. Und sie schaffen ein einheitliches Äußeres, das es für die Leser/Nutzer einfacher macht, eine Webseite zu konsumieren. Am Ende ist es das Wichtigste, dass Kunden/Leser mit einer Webseite zurecht kommen und nicht, dass ein Redakteur seiner künstlerischen Ader freien Lauf lassen kann.

5. Jedes Modul ist eine eigene Welt

Damit wir im Frontend wirklich modular entwickeln, müssen wir auch die entstehenden Module als eigene Einheiten verstehen. Im CSS beginnen die Selektoren dementsprechend mit dem Modul selber oder einem seiner Bestandteile. Sie sollten immer verhindern, einen Teil des umgebenden DOM mit in die Selektoren zu schreiben.

 1 /* --------- So macht man das! ------------ */
 2 /* Das Modul steht für sich. */
 3 
 4 .videowrapper {
 5     /*  Eigenschaften */
 6 }
 7 .videowrapper iframe {
 8     /* Eigenschaften */
 9 }
10 
11 
12 /* ----------- keine gute Idee! ------------ */
13 /* Was, wenn der Videowrapper demnächst in einem
14       anders benamten Container stecken sollte? */
15 
16 .maincnt .videowrapper {
17     /*  Eigenschaften */
18 }
19 .maincnt .videowrapper iframe {
20     /* Eigenschaften */
21 }

Die zweite hier vorgestellte Vorgehensweise ist sehr stark verbreitet. Dabei wird der Selektor meist noch viel mehr aufgebläht. Manchmal wird fast das gesamte DOM abgebildet. Das hat zwei Nachteile:

  1. Die Spezifität wird (stark) erhöht, sodass es immer schwerer wird, Abweichungen zu definieren. Selbst die Modifikatorklassen würden einen ähnlich komplexen Selektor benötigen. Oder man resigniert und verteilt “!important”.
  2. Die Abbildung von Selektoren vor dem Modul macht das Modul schwer transportabel. Man könnte es in einem anderen Projekt nur dann nutzen, wenn auch dort eine gleich benannte, ähnlich aussehende Struktur existierte. Sollte sich die Struktur der Webseite zwischen Planung und Endversion oder zwischen zwei Projekten grundlegend ändern, ist die Wahrscheinlichkeit hoch, dass solche Selektoren nicht mehr ziehen werden.

Jedes Modul sollte für sich selbst stehen. Wenn dem so ist, dann kann man prinzipiell einen Produktteaser in den Header oder Footer platzieren und er sieht noch immer wie gewünscht aus. Nicht, dass dieses Vorgehen sinnvoll wäre, es wäre aber der ultimative Test.

Erfolgreiche UI-Frameworks wie Bootstrap oder Foundation funktionieren exakt so. Auf den jeweiligen Übersichten stehen bspw. mehrere Navigationen untereinander, die von Formularen und Tabellen gefolgt werden können. Alle sind aus einem etwaigen Zusammenhang gerissen und sehen trotzdem wie gewünscht aus.

Machen Sie den Test mit Ihrem eigenen Projekt: Erstellen Sie eine Datei ohne den üblichen Rahmen. Nutzen Sie ein vollkommen neues Grid, das Sie in Ihrem Projekt nicht nutzen und platzieren Sie dann mehr oder minder willkürlich die Module Ihrer Webseite auf dieser Testseite. Sie werden nun auf einen Blick sehen, welche Module eine bestimmte Struktur benötigen, damit sie wie gewünscht aussehen. Mit dem CSS dieser Module beginnen Sie dann die Überarbeitung Ihres Projektes.

Module identifizieren

Bevor wir Module gestalten, müssen wir sie erst einmal identifizieren. Dafür nehmen wir uns das Design in all seinen Ausprägungen und schauen zuerst nach einmalig vorkommenden Seitenbestandteilen. Normalerweise sind dies alle Elemente des Headers und des Footers. Sodann schauen wir nach Seitenbestandteilen, die identisch oder ähnlich mehrfach vorkommen. Die Ähnlichkeit ist dabei durchaus wichtig. Denn wenn es neben einem Container mit einer einfachen Linkliste auch einen gibt, bei dem neben den Links auch Icons abgebildet sind, so rechtfertigt diese eine Abweichung nicht, daraus ein eigenständiges Modul zu machen und damit viel duplizierten Code zu schreiben.

Stattdessen sollte die Abweichung über eine oder mehrere ergänzende Klassen geregelt werden. Später taucht dieser Ansatz als “Modifikator” noch einmal auf. Die beiden folgenden Screenshots sind eine starke Simplifizierung, aber sie weisen darauf hin, dass nur der Wechsel des Aufzählungszeichens kein vollkommen neues Modul kreiert. Es handelt sich in beiden Fällen um eine Liste. Die Sterne als Aufzählungszeichen sind entweder der Standard oder die Abweichung. Aber sie rechtfertigen nicht, ein neues Modul mit umfangreichen Styleanweisungen zu erstellen.

Ein Teaser mit einer ungestylten Liste
Ein Teaser mit einer ungestylten Liste
Bei diesem Teaser haben die Listenelemente Sterne als Aufzählungszeichen
Bei diesem Teaser haben die Listenelemente Sterne als Aufzählungszeichen

Zur Orientierung, welche Module existieren, empfehle ich, die Designs auszudrucken und im wörtlichen Sinne auseinanderzuschneiden. In kleinen Schnipseln auf einem großen Tisch oder an der Wand klebend können Sie kleine Haufen und Inseln bilden. Sie identifizieren dadurch viel schneller Ähnlichkeiten. Ein Computermonitor schränkt durch seinen zur Verfügung stehenden Platz sehr ein.

Am Namen sollst Du sie erkennen

Klassen zu benennen ist nicht einfach. Abseits der später besprochenen Methodiken, die ihre eigenen Ideen haben, bleibt die grundsätzliche Frage der Klassennamen. Aus der Praxis gebe ich folgende Regeln als Ratschläge:

  1. Englische Namen sind deutschen vorzuziehen, denn sollte man Hilfe bspw. in Stackoverflow benötigen oder der Templatesatz zur Weiterbearbeitung ins Ausland gehen, helfen deutsche Klassennamen nicht weiter.
  2. Die Klassennamen sollten nicht eng an die Optik gekoppelt sein. Eine Klasse .blue ist nur solange praktisch, bis man die damit verbundene Gestaltung auf Kunden- oder Designerwunsch in rot ändern muss. Dann gibt die Klasse .blue auf einmal rote Ergebnisse.
  3. Zu enge inhaltliche Verknüpfungen sind aber auch nicht praktisch, denn eine .sponsortable kann prima auch für eine Tabelle genutzt werden, in der Kundenlogos stehen. .imagetable wäre evtl. eine bessere Wahl. Der Name sollte also eine gesunde Balance zwischen Abstraktion und inhaltlicher Beschreibung wahren. Das ist nicht einfach, aber ein erreichbares Ziel.

6. Differenz zwischen Design und Realität

Egal welche Vorgehensweise wir nutzen, wir sollten immer im Blick behalten, dass der Designer nur einen idealisierten Zustand entwirft. Gerne nutzen Designer einfache, kurze Überschriften oder Navigationseinträge, damit die Optik kompakter, angenehmer wirkt. Genauso enden auch nebeneinander stehende Container gerne auf der gleichen Höhe. Das tun sie auch dann, wenn sie nicht im gleichen semantischen Kontext platziert sind.

Der Entwurf des Designers ist ein nach optischen Gesichtspunkten erstellter Zustand. Er sollte uns für die Realisierung nicht unnötig irritieren. Deshalb plädiere ich dafür, sehr frühzeitig im Entwicklungsprozess mit möglichst realistischen Inhalten zu arbeiten.

Vor Jahren arbeitete ich mit einem Freund und Kollegen am Relaunch eines inhaltsstarken Verlagsangebotes. Dabei wurde auch ein Kommentarwidget entworfen, das aus einem externen Tool gespeist werden sollte. Dummydaten hatten wir keine, deshalb sah der erste Entwurf folgendermassen aus:

Erster Kommentarentwurf
Erster Kommentarentwurf

Die verlinkten Kommentarauszüge sind recht knapp gehalten, deshalb ist das ganze Modul nicht besonders hoch. In der Liveseite wurden die Kommentarauszüge umfangreicher, die Namen länger und dadurch das ganze Modul größer.

Kommentare mit realistischen Inhalten
Kommentare mit realistischen Inhalten

Da die zusätzlichen Inhalte vertikalen Raum einnahmen, entstand daraus kein Designproblem. Schlimm wäre es gewesen, wenn sich diese Diskrepanz zwischen Planung und Realität auf ein horizontal ausgerichtetes Designelement ausgewirkt hätte, wie beispielsweise die horizontale Navigation oder die Breadcrumb.

Realistische Dummy-Inhalte nutzen

Der Wert eines Designs oder eines Moduls wächst mit der Verwendung realistischen Inhalts. Kann der Kunde noch keine fertigen Texte liefern, so können Sie entweder auf die alten Inhalte oder zumindest auf passenden Blindtext zurückgreifen. Bei deutschsprachigen Websites sollten Sie dementsprechend immer deutschen Blindtext nutzen. Und speziell in horizontalen Navigationen sollten die Linknamen nicht zu kurz sein. Es ist ein entscheidender Unterschied, ob man eine horizontale Navigation nur mit “Item 1”, “Item 2” usw. füllt oder ob man realistische Linktexte nimmt. Die deutsche Sprache hat viele lange Worte und bei horizontalen Navigationen ist der Platz limitiert. Deshalb empfehle ich immer, “Arbeiterstrandbadstraße” in eine Navigation einzufügen. Der Name einer Wiener Haltestelle ist ein prima Beispiel für einen komplexen, langen Navigationseintrag. “Wirtschaft & Soziales” oder “Schule & Hochschule” sind ähnlich praktisch. Lange Linktexte lassen möglicherweise Probleme in einer horizontalen Navigation erscheinen, die auf den ersten Blick verborgen gewesen sind.

Kann der Kunde nicht frühzeitig Inhalte liefern, sollte er zumindest eine vorläufige Inhaltsstruktur und damit auch Navigationspunkte kommunizieren. Sie sollten möglichst früh mit realistischen Inhalten arbeiten. Dummy-Inhalte erscheinen möglicherweise als eine Nebensächlichkeit, sind sie aber nicht. Bindet man an Stelle der zuerst genutzten grauen Bildattrappen später aussagekräftige Bilder ein, ergeben deren Farben mit dem Design der Seite einen vollkommen neuen Eindruck. Es gibt im Internet zahllose Dienste für Platzhalterbilder mit echten Motiven, anstelle einfacher grauer Platzhalter mit Dimensionsangaben.

Auch bei Blindtext kann man eine Menge falsch machen. Das beliebte “Lorem ipsum” ist nur angebracht, wenn man eine Seite für einen Lateinkurs erstellen möchte. Für deutschsprachige Seiten ist es ungeeignet, denn Deutsch hat viel längere Worte, mehr Unterlängen und vor allem Umlaute. Insgesamt ergibt sich ein komplett anderes Schriftbild. Das ist durchaus von Bedeutung. Denn oft haben wir es bei Layouts mit kleinräumigen Boxen zu tun. In diese passen oft kaum zwei lange Worte. Auch Überschriften können schnell zweizeilig werden. Ist dann der Raum für die Überschrift auch noch in der Höhe limitiert, hat der Nutzer das Nachsehen.

Quellen für realistische Dummy-Inhalte

Die größte Auswahl an unterschiedlichen Platzhalterbildern bietet sicherlich lorempixel. Deren Bilder bindet man schlicht durch einen direkten Link mit den gewünschten Dimensionen des Bildes ein. Man kann sich dabei komplett ein zufälliges Bild liefern lassen, es aber auch thematisch eingrenzen. Für Blindtexte empfehle ich den Blindtextgenerator. Er bietet eine große inhaltliche Bandbreite, man kann die Wörter oder Zeichen beschränken, die Anzahl der Absätze wählen und auch gleich HTML mit ausgeben lassen. Zudem liegen die Texte in vielen Sprachen vor.

Solange man keine vom Kunden gelieferten Testdaten hat, können Bilder und ein paar Texte noch immer zu wenig sein. Es gibt noch mehr Platzhalter-Inhalte. Unter GenerateData.com kann man sich Testinhalte als Tabelle, CSV-Datei, Excel, JSON, XML oder SQL ausgeben lassen. Die Anwendung ist dafür gedacht, falsche Personenprofile zu erschaffen. Möchte man dann ein Nutzerprofil erstellen und ein Profilbild fehlt, kann man sich bei UIFaces bedienen. Richtig komplexe Nutzerprofile kann man sich vom FakeNameGenerator erstellen lassen. Möchte man all diese Aufgaben an ein PHP-Skript übertragen, so gibt es auch dieses. Eine weitere interessante Seite ist Lists. Dort findet man sehr viele Listen mit sehr unterschiedlichen Inhalten. Diese kann man im JSON-Format herunterladen.

Das Ergebnis sollen halbwegs realistische Inhalte sein. Sie sind unsere Kontrolle, ob das Layout nicht nur in der Theorie, sondern auch in der Praxis funktioniert.

7. Unterschiedliche Arten zu stylen

Grundsätzlich stehen uns viele unterschiedliche Arten zur Verfügung, um mittels CSS Gestaltung an die HTML-Elemente und ihre Inhalte zu bekommen. Alle haben sie ihre Berechtigung, keine ist wirklich falsch. In dieser Abhandlung dreht sich alles um wiederverwendbare Module. Dabei sind beide Aspekte wichtig:

  1. Wiederverwendbarkeit innerhalb des Projektes und zwischen Projekten
  2. Module im Sinne abgekapselter Inhalte

Da mir diese beiden Aspekte sehr wichtig sind, fällt für mich die Möglichkeit aus, nur mit Element- und Pseudoselektoren unter Ausnutzung unterschiedlicher Kombinatoren zu gestalten.

Wir haben in meinen Augen zwei grundsätzlich unterschiedliche Ansätze zur Verfügung, wie wir Module unseres Designs gestalten und modifizieren können:

  1. Wir vergeben eine Basisklasse und ergänzen sie optional durch einen oder mehrere Modifikatoren. Damit gestalten wir also durch eine Klasse oder eine Kombination mehrerer.
  2. Wir regeln alle Abweichungen und Standards im CSS und vergeben nur jeweils eine einzelne Klasse.

Ein gern genommenes Beispiel sind hier Buttons. Im Modifikatoransatz würden wir eine Basisklasse vergeben, die schon eine Designvariante darstellt. Der Modifikator ändert dann Details wie Größe, Farben oder Icons.

1 <!-- Standardbutton -->
2 <button class="btn">Klick mich!</button>
3 
4 <!-- Button mit warnender Farbe -->
5 <button class="btn btn-warning">Warnung</button>
6 
7 <!-- Link als Button formatiert, mit Icon -->
8 <a href="#" class="btn btn-ico-print">drucken</a>

Der auf das CSS fokussierte Ansatz ist dann besonders praktisch, wenn man einen Präprozessor nutzt. Vor allem Sass ist hierbei empfehlenswert, denn Sass bietet das Konzept der Platzhalter (placeholder). Mit Platzhaltern verschiebt man die allgemeingültige Klasse in eine stille Helferklasse, die dann wiederum von allen einzelnen Ausprägungen aufgerufen wird. Dadurch müssen nicht mehr mehrere Klassen auf ein Element gesetzt werden. Die Referenzierung auf die Eigenschaften der einen Basisklasse geschieht über den Platzhalter.

 1 %btn { 
 2   /* Platzhalter mit allgemeiner Buttondefinition */
 3 }
 4 
 5 /* Standardbutton */
 6 /* Mit @extend werden die Eigenschaften von %btn über\
 7 nommen.
 8    Am Ende werden mehreren kommaseparierten Selektoren
 9    die Eigenschaften zugewiesen, die identisch sind. \
10 */
11 .btn {
12   @extend %btn;
13 }
14 
15 /* Button mit warnender Farbe */
16 .btn-warning {
17   @extend %btn;
18   color: $btn-warning-col;
19   background-color: $btn-warning-bgcol;
20 }
21 
22 /* Link als Button formatiert, mit Icon */
23 .btn-ico-print {
24   @extend %btn;
25   color: $btn-ico-print-col;
26   padding-left: 10px;
27   background: $btn-ico-print-bgcol image-url($btn-ico\
28 -print-icon) no-repeat left center;
29 }

Allerdings bestimmt die Positionierung der Platzhalter innerhalb des gesamten SCSS-Konstruktes die Position der Ausgabe. Diese ist normalerweise nicht an der gewünschten Stelle. Ich habe das in einem Beispiel bei Sassmeister demonstriert. Setzen Sie also Platzhalter am Besten direkt an den Anfang der Modul-Datei - nicht in eine separate Datei. Oder nutzen Sie Mixins an Stelle von Platzhaltern.

Der erste Ansatz, bei dem durch Klassen im HTML gestaltet wird, ist sehr gut geeignet für Rapid Prototyping, da man sich auf Inhalt und Struktur konzentrieren kann. Zur Gestaltung muss das CSS weder geschrieben noch modifiziert werden. Einfache Regeln ermöglichen ein grundsätzliches Design, an dem dann später eventuell weitergearbeitet wird. Allerdings werden viele Klassen in das HTML geschrieben. Und eine Designänderung erfordert eine Änderung am HTML (Austausch einer Klasse), anstatt diese im CSS vorzunehmen.

Beim zweiten, auf das CSS konzentrierten Ansatz, werden wenige Regeln dupliziert. Das CSS wächst unweigerlich an, dafür bleibt das HTML ein wenig kompakter.

Es ist unnötig, sich theoretisch für eine der beiden Varianten zu entscheiden. Aus der konkreten Projektsituation heraus sollte einer der beiden Wege eingeschlagen, dann aber auch konsequent zu Ende gegangen werden.

8. Die objektorientierten Ansätze

Nicole Sullivan trat mit ihrem Ansatz “Object Oriented CSS” - kurz OOCSS - eine Lawine los. In ihrem Fahrwasser machten sich immer mehr Entwickler Gedanken über den richtigen Aufbau ihrer Stylesheets. Mit SMACSS und BEM entstanden zwei ebenfalls sehr einflussreiche Ansätze, die im Folgenden auch besprochen werden.

Die Argumentation geschieht dabei immer in Anlehnung an die objektorientierte Programmierung, obwohl es sich weder bei HTML noch bei CSS um eine Programmiersprache handelt. Möglicherweise wurde der Name mehr mit Gedanken an Marketing, als an Inhalte gewählt. “Module” wären der passende Begriff, nicht “Objekte”. Denn am Ende dreht sich alles um visuelle Muster, die im CSS abgebildet werden sollen.

OOCSS, SMACSS und BEM sind sich in ihrer Grundausrichtung ähnlich. Sie gehen alle mit einer leicht unterschiedlichen Sichtweise an die Sache heran, aber sie ähneln sich doch stark:

  • Die einzelnen Seitenelemente werden als Objekte betrachtet.
  • Seiten sind immer Zusammenstellungen mehrerer dieser Objekte und werden nie als Einheit betrachtet.
  • Alle Objektbestandteile werden mittels Klassen angesprochen.
  • Die Benamung der Klassen folgt einer rigide exekutierten Logik.
  • Alle Ansätze entstammen der Beschäftigung mit großen, komplexen Webseiten und komplexen Teams.
  • OOCSS und BEM gehen nur von Klassen als Selektoren aus, SMACSS verwendet zumindest hin und wieder Attributselektoren oder Elemente.
  • Die Nutzung von IDs ist verpönt, quasi verboten.

Allen Ansätzen halte ich zu Gute, dass sie den Blick auf wichtige Details geschärft haben, dass sie einen Ansatz liefern, mit immer komplexer werdenden Stylesheets umzugehen. Sie bieten eine Basis für die Entwicklung eigener Best Practices. Als solches sollte man sie sehen, nicht als heilige Schrift. Leider ist Letzteres zu oft der Fall.

Objektorientiertes CSS und Semantik

Der Fokus der im Folgenden diskutierten Ansätze liegt immer auf der Organisation und Schreibweise des CSS. HTML wird dabei eigentlich immer vernachlässigt. Das führt in der uninformierten, undurchdachten Anwendung gerne dazu, dass die Semantik vernachlässigt wird. So entstehen unnötige DIV-Wüsten und die Existenz des button-Elements scheint in Vergessenheit zu geraten. Schliesslich können die passenden Styles jedem beliebigen Element mit der passenden Klasse gegeben werden. Ein wenig JavaScript macht dann auch ein span-Element interaktiv.

Die objektorientierten Ansätze propagieren eine gewisse Form der Abstraktion. Diese gilt für das CSS. Sie sollte nicht für das HTML gelten. Das HTML sollte auch ohne CSS noch Sinn ergeben und ist von BEM und Konsorten unbeeindruckt.

OOCSS

Unter dem Eindruck allzu umfangreicher Stylesheets in Großprojekten entwickelte Nicole Sullivan den Ansatz OOCSS. Das Ziel war die bessere Skalierbarkeit, vor allem in großen Teams. Dafür suchte sie nach Wiederholungen, Mustern und leicht korrigierbaren Abweichungen in den Styles der einzelnen Module.

Sullivan trennte dann Basis-Styles für Module von Designinformationen, die eventuell modulübergreifend nutzbar sind. Zusätzlich trennte sie Designinformationen von Semantik, indem sie komplett auf die Verwendung von Klassen baute, anstatt Elementselektoren zu nutzen. Das führt zu zwei einfachen Regeln:

  1. Trenne Struktur und Darstellung.
  2. Trenne Container (des Moduls) und Inhalt.

Im Gegensatz zu den nachfolgenden Konzepten ist OOCSS recht einfach und schmal. Es macht mehr den Eindruck einer durchdachten Skizze. Es gibt bspw. keine Nomenklatur für Klassennamen. Lange Zeit gab es wenig Implementierungsbeispiele. Mittlerweile ist das Projekt gewachsen, wenn auch immernoch übersichtlicher, als die anderen Protagonisten.

OOCSS lässt sich auf einige wenige Klassen eindampfen, die global nutzbar sein sollen. Eine Modulklasse, bei Sullivan beispielhaft .mod genannt, beinhaltet optionale Elemente mit den Klassen .hd (Header), .bd (Body) und .ft (Footer). Diese Elemente werden dann noch in einen Wrapper namens .inner gepackt. Dieser erklärt sich aus der Entstehungszeit. Denn um 2006 herum waren die alten IE noch sehr verbreitet, die Kunden wollten aber trotzdem auch für diese die beliebten runden Ecken haben. Den .inner-Container benötigte Sullivan also primär als zusätzlichen Hook, um Bilder für runde Ecken zu platzieren. Mit modernen HTML5-Elementen könnte das idealtypische OOCSS-Modul also folgendermaßen aussehen:

 1 <div class="mod">
 2   <header class="hd">
 3     <h3>Tolle Headline</h3>
 4   </header>
 5 		<div class="bd">
 6       <p>Toller Inhalt</p>
 7 		</div>
 8     <footer class="ft">
 9     Was auch immer hier stehen soll
10   </footer>
11 </div>

Sullivan verortet die Klassen bewusst auf DIV-Elemente, die als Wrapper für die eigentlichen Inhalte dienen. Sie rät bewusst davon ab, Elementselektoren in CSS-Regeln mit aufzunehmen. Dann dadurch gibt es eine Abhängigkeit des CSS vom eingesetzten HTML und die Spezifität der Regeln verändert sich.

Da wir im Gegensatz zur Entstehungszeit von OOCSS mittlerweile über neue HTML5-Elemente verfügen und alle modernen Browser die grundlegenden CSS3-Eigenschaften beherrschen, dürfte auch Nicole Sullivan nichts dagegen haben, wenn wir die Klasse .hd direkt an die Überschrift setzen und uns so eine DOM-Ebene sparen. Ob wir einen zusätzlichen Wrapper benötigen kann schlicht vom zu erreichenden Design abhängen.

Eine weitere schöne Idee von Sullivan war, Abweichungen im Design eines Moduls durch Modifikatoren zu realisieren. Das Modul kann also auch folgendermassen aussehen:

1 <div class="mod light">
2   <h3 class="hd">Tolle Headline</h3>
3   <p>Toller Inhalt</p>
4 </div>

Die Klasse .light sorgt dafür, dass das Modul abweichend von der normalen Formatierung aussieht. Ich empfehle, regen Gebrauch von solchen Modifikatoren zu machen und diese dabei im Wesentlichen immer nur eine Eigenschaft modifizieren zu lassen. Sie sind dann im Einsatz flexibler. Wenn Sie also Hintergrundfarbe, Rahmen und die Floatrichtung eines Bildes modifizieren wollen, dann schreiben Sie für jede diese Änderungen eine separate Klasse.

Am Ende können drei oder mehr Modifikatoren eine Klasse ergänzen. Das ist kein Problem. Wir selber verlieren sehr viel schneller die Übersicht, als der Browser vor der Masse der Klassen einbricht. Irgendwann nach 2000 Klassen ist bei den IEs eine Grenze. Wir haben schon viel früher die Übersicht verloren. Deshalb spricht nichts dagehen, ein Modul mit fünf oder zehn Modifikatoren zu ergänzen und so sparsames CSS zu schreiben.

SMACSS: Unterschiedliche Einzelteile des CSS

Jonathan Snook nimmt mit seinem Ansatz SMACSS - Akronym für Scalable and Modular Architecture for CSS - eher eine Dokumentenperspektive ein. Er analysiert die unterschiedlichen Einsatzzwecke für CSS und kategorisiert dadurch seine Styles. Obwohl auch Snook Webseiten als Ansammlung von Modulen betrachtet, sieht er mehrere wichtige Ebenen, nicht nur die der Module. Folgende fünf Bereiche werden identifiziert:

  1. Base
  2. Layout
  3. Module
  4. State (Zustand)
  5. Theme

Base-Styles sind die Reset- oder Normalisierungs-Styles eines Projekts. Bei den Layout-Styles handelt es sich üblicherweise um ein Grid- oder Spaltensystem. Die Module werden in Aufbau und Gestaltung beschrieben. Die State-Styles sind Regeln, die für den Zustand eines Moduls zuständig sind. Also beispielsweise die Gestaltung eines geöffneten bzw. geschlossenen Items in einem Akkordeon.

Mittels Theming kann man einem Projekt eine andere Identität geben und so aus einer einzigen Basis mehrere Kundenprojekte kreieren. Im Grunde kann man den optischen Eindruck als Theming sehen. Trennt man dies vom Rest der Regeln, hat man ein Set an Gestaltungsregeln, die man gezielt manipulieren kann, um einen veränderten Eindruck zu erwecken.

Snook führt in seinem Ansatz auch Namenskonventionen ein. Diese erleichtern die Zuweisung von Styles zu einem der oben genannten fünf Bereiche. So werden State-Styles mit .is- oder .has- begonnen, Layout-Styles haben .l- oder .layout- als Prefix. Module hingegen bekommen keinen Prefix, stehen für sich.

Ich finde SMACSS sinnvoll, um sich die Eigenarten eines Projektes und die unterschiedlichen Aufgabenbereiche der Gestaltung klar zu machen. Auch die Prefixes für State-Styles finde ich sehr praktisch.

BEM (Block, Element, Modifier)

Von der russischen Suchmaschine Yandex stammt der Ansatz BEM. Das Akronym steht dabei für “Block, Element, Modifier”. Ein Modul einer Webseite wird als “Block” bezeichnet. Dieser besteht wiederum aus mehreren Elementen. Die Darstellung dieser Elemente kann durch “Modifier” verändert werden.

In der Doku wird eine Navigation als Beispiel genommen. Die Navigation selber ist hierbei der Block. Die einzelnen Links - egal wie sie gestaltet sind - sind die Elemente. Die Formatierung als vertikale oder horizontale Navigation, als Reiter oder Buttons, geschieht dann über die Zuweisung der passenden Modifier.

Wir haben also eine Trennung zwischen Grundstyles und Modifikationen. Auch der BEM-Ansatz geht davon aus, dass wir kein komplett neues Modul benötigen, nur weil es anders aussieht, als ein in der Struktur ähnliches oder gleiches.

Insbesondere die BEM-Nomenklatur hat in der letzten Zeit viele Fürsprecher gefunden. Anscheinend besticht ihre schlichte und strikte Logik. Die dadurch entstehenden langen Klassennamen scheinen nicht alle Entwickler abzuschrecken.

Die drei Bestandteile des BEM-Ansatzes werden sauber durch die Benennungsregeln identifizierbar. Dabei werden doppelte Binde- und Unterstriche genutzt. Die Grundidee ist Folgende:

1 .block {}
2 .block__element  {}
3 .block--modifier {}
4 .block__element--modifier {}

In einem praktischen Beispiel kann das dann so aussehen:

1 .speech-bubble{}
2 .speech-bubble__header{}
3 .speech-bubble__text{}
4 .speech-bubble__text--link{}

Die einzelnen Elemente und Modifier werden im Grunde genommen mit dem Namen des Moduls als Namespace versehen. Das passiert, um eine niedrige Spezifität zu bewahren. Doch genau mit dieser Begründung habe ich mein Problem.

Es macht für mich im Endergebnis keinen Unterschied, ob eine Regel eine hohe oder niedrige Spezifität hat, wenn ich diese Regel sowieso nur auf einen kleinen, begrenzten Einsatzzweck beschränken möchte. Für den Erfolg einer Arbeit ist es unerheblich, ob im CSS .speech-bubble__header {} oder .speech-bubble .header {} steht. Weder im CSS noch im HTML benötigen wir die Pseudo-Namespaces, um eine Zuordnung machen zu können. Im HTML stehen die Elemente direkt innerhalb des Moduls, im CSS gruppiert man sinnvollerweise alle zu einem Modul gehörenden Styles an einem Ort. Nutzt man einen Präprozessor, wird dies durch Verschachtelung vereinfacht.

Die höhere Spezifität meines Alternativbeispiels ist unerheblich, denn das Ergebnis ist das Gleiche. Da ich meine Elemente nicht mit einem Modulprefix versehe, kann ich sie in unterschiedlichen Modulen nutzen. Da ich die Klassen der Elemente aber im Kontext der Modulklassen aufrufe, wirkt dies so, als hätte ich ein Modulprefix gesetzt.

Bei BEM wird eine Klasse nur innerhalb eines Moduls genutzt. Die mehrfache Nutzung einer Klasse innerhalb verschiedener Module ist nicht vorgesehen, schliesslich arbeiten alle Klassen mit einem Modulprefix.

Bei beiden Vorgehensweisen gibt es keine Konflikte. Beim von mir vorgeschlagenen Vorgehen kann ich hingegen sogar Gemeinsamkeiten auslagern.

Im Endergebnis muss man bei BEM immer mit langen und noch längeren Klassennamen umgehen. Dabei ist der lange Klassenname, der einmalig im Kontext eines Moduls genutzt wird, auch nicht besser als ein allgemeinerer Name, der in mehreren Modulen genutzt wird, aber nur im Kontext des Moduls gestaltet wird.

9. Strikte Regeln können sinnvoll sein

Ich bin bei der Bewertung der Benamungsrichtlinien von mir ausgegangen. Diese Konzepte wurden allerdings im Rahmen sehr großer Teams entwickelt (bspw. Yahoo und Yandex), bei denen die CSS-Kompetenzen sicherlich sehr ungleich verteilt waren. In solchen Teams sind strikte Regeln ein Segen. Speziell wenn Entwickler dabei sind, die weder die Kaskade noch Spezifität kennen oder begriffen haben.

Wenn man aber allein arbeitet oder in kleinen Teams, in denen die Beteiligten Ahnung von der Materie haben, dann empfehle ich ein weniger striktes Vorgehen. Es könnten ansonsten Motivation und Effizienz darunter leiden.

Wenn Sie also allein für das CSS zuständig sind oder Ihre Kollegen ihr Handwerk auch recht gut beherrschen, dann spricht nichts dagegen, die strikten Benennungsregeln ein wenig aufzuweichen.

Sind Klassen wirklich klasse?

Alle objekt-orientierten Ansätze empfehlen den ausschliesslichen Einsatz von Klassen. Sie sollen helfen, CSS und HTML zu entkoppeln. Elemente sollen im CSS nicht mehr direkt angesprochen werden. Einzig SMACSS geht hier pragmatischer vor und beschreibt auch die Kombination von Klassen mit Element- oder Pseudoselektoren.

Ich denke, die Praxis heutiger CM-Systeme widerspricht dem radikalen Ansatz. Inhalte werden üblicherweise von Redakteuren innerhalb eines CMS in einen Editor eingegeben. Diese Inhalte können mehrere Absätze und Listen oder sogar Tabellen umfassen. Spricht man innerhalb des CSS nun nicht mehr die einzelnen Elemente an, müssten die Redakteure zwingend auch Klassennamen im WYSIWYG-Editor vergeben können, damit die Gestaltungsregeln greifen.

Dies ist ein Eingriff, den ich keinem Redakteur zumuten möchte. Dieser weiss oft mit der dahinterliegenden Technik nichts anzufangen oder fühlt sich im schlimmsten Fall zu Designexperimenten bemüssigt. Der Redakteur sollte sich einzig auf seine Inhalte konzentrieren.

Doch auch in Fällen, in denen der Frontendentwickler volle Kontrolle über das HTML besitzt, erscheint mir eine intensive Nutzung von Klassen nicht immer notwendig. Insbesondere bei einfachen Navigationen und Tabellen sehe ich keinen Gewinn darin, jedem Element eine Klasse zu geben. Nach BEM-Richtlinien sollte eine Navigation folgendermaßen ausgezeichnet werden:

 1 <ul class="navigation">
 2   <li class="navigation__item">
 3     <a href="#" class="navigation__link">Link</a>
 4   </li>
 5   <li class="navigation__item">
 6     <a href="#" class="navigation__link">Noch ein tol\
 7 ler Link</a>
 8   </li>
 9   <li class="navigation__item">
10     <a href="#" class="navigation__link">Der ist noch\
11  besser!</a>
12   </li>
13 </ul>

Das dazugehörige CSS sähe dann folgendermassen aus:

1 .navigation { /* Eigenschaften */ }
2 .navigation__item { /* Eigenschaften */ }
3 .navigation__link { /* Eigenschaften */ }

Doch eine einstufige Navigation (ohne Unternavigation!) besteht nur aus einer Liste, deren einziges direktes Kindelement das Listenelement li sein kann. Darin ist dann ein Link geschachtelt. So weit so einfach. Deshalb empfinde ich folgende Auszeichnung wesentlich sinnvoller:

 1 <ul class="navigation">
 2   <li>
 3     <a href="#">Link</a>
 4   </li>
 5   <li>
 6     <a href="#">Noch ein toller Link</a>
 7   </li>
 8   <li>
 9     <a href="#">Der ist noch besser!</a>
10   </li>
11 </ul>

Das dazugehörige CSS sähe dann so aus:

1 .navigation {/* Eigenschaften */}
2 .navigation li {/* Eigenschaften */}
3 .navigation a {/* Eigenschaften */}

In solch eng abgrenzbaren Fällen, in denen wir eine klare, nicht zu verändernde Struktur erwarten können, empfinde ich es wohltuend, Klassen im HTML einzusparen und die in CSS aus guten Gründen vorgesehenen Elementselektoren zu nutzen. Aber schon bei einer Navigation mit Subnavigation(en) nehme ich wieder Abstand von der oben beschriebenen Ausnahme. Der Nutzen von Klassen ist in solchen Momenten einfach zu hoch:

 1 <ul class="navigation">
 2   <li class="navigation__first-level-item">
 3     <a href="#" class="navigation__first-level-link">\
 4 Link</a>
 5   </li>
 6   <li class="navigation__first-level-item">
 7     <a href="#" class="navigation__first-level-link">\
 8 Noch ein toller Link</a>
 9 
10     <ul class="navigation__second-level">
11       <li class="navigation__second-level-item">
12         <a href="#" class="navigation__second-level-l\
13 ink">Link im Submenü</a>
14       </li>
15       <li class="navigation__second-level-item">
16         <a href="#" class="navigation__second-level-l\
17 ink">Noch ein Link im Submenü</a>
18       </li>
19       <li class="navigation__second-level-item">
20         <a href="#" class="navigation__second-level-l\
21 ink">Link im Submenü</a>
22       </li>
23     </ul>
24   </li>
25   <li class="navigation__first-level-item">
26     <a href="#" class="navigation__first-level-link">\
27 Der ist noch besser!</a>
28   </li>
29 </ul>

Ich sehe durchaus den Nutzen strikter Regeln. Sollten aber die Projektbeteiligten genügend CSS-Wissen besitzen, empfinde ich begründete Ausnahmen von der Regel als einen Segen. Sie vermeiden unnötig zugemülltes HTML.

Sind IDs wirklich böse?

Neben der übermässigen Nutzung von Klassen plädieren alle objektorientierten Ansätze vehement gegen die Nutzung von IDs innerhalb von CSS. Schliesslich hätten sie eine zu hohe Spezifität und könnten nicht mehrfach auf einer Seite genutzt werden. Die reine Verteufelung der Nutzung von IDs zur Gestaltung ist in meinen Augen recht sinnfrei. Aber sie schärft die Sinne für die Frage der Nützlichkeit und Notwendigkeit von IDs.

Manche CM-Systeme geben von selbst IDs aus und lassen sich dies entweder nur schwer oder gar nicht abgewöhnen. Das bedeutet für sich genommen noch nichts. Man muss die zur Verfügung gestellten IDs schliesslich nicht im CSS nutzen.

Ich sehe hingegen einen begrenzten Nutzen für IDs im CSS. In der Vergangenheit habe ich IDs oft für die konstruierenden Bereiche eines Layouts genutzt. So kann ich #header, #main, #sidebar, #footer direkt ansprechen und gestalten. Das kann sinnvoll sein, denn die korrespondierenden HTML5-Elemente header und footer können mehrfach auf einer Seite verwendet werden.

Ich stelle immer sicher, dass ich IDs nur für einmalige Zwecke nutze. Das betrifft grundsätzlich die Basisbausteine meines Layouts, es kann auch das Logo betreffen. Klassen sind und bleiben hingegen das gängigste Mittel der Wahl für die Gestaltung von Webseiten. Denn schliesslich ist es unser Bestreben, einen möglichst sparsamen CSS-Verbrauch am Ende zu haben. Das schaffen wir, wenn wir viele Regeln mehrfach verwenden können.

Die objektorientierten Ansätze plädieren gegen die Nutzung von IDs, würden dafür lieber Klassen einmalig auf einer Seite vergeben. Ich kann mich dem nicht anschliessen, finde dies eher verkrampft, als zielführend. Allerdings finde ich auch, dass es wichtigere Streitpunkte bei der Abfassung eines Stylesheets gibt, als die punktuelle Nutzung von IDs.

10. Entkoppelung von HTML und CSS

Die Idee, HTML und CSS voneinander zu entkoppeln, hört sich auf den ersten Blick charmant an, darf aber nicht falsch verstanden werden.

Gestaltung und Semantik können vollständig voneinander entkoppelt werden, indem wir nur noch mit Klassen arbeiten, Elementselektoren nicht mehr nutzen. Dadurch ist es vollkommen egal, ob wir mit der Klasse .code einen Link, einen Button, einen DIV-Container oder eine h3 stylen, alle werden dank der Klasse gleichartig gestaltet.

Allerdings schreiben wir unser CSS immer für einen konkreten Gestaltungsfall. Deshalb ist es unwahrscheinlich (obgleich durchaus möglich), dass wir die Klasse .teaser__headline zur Gestaltung eines Buttons anwenden. Der Nutzen der Klasse .teaser__headline liegt allerdings darin, dass wir bei ihrer Gestaltung nicht wissen müssen, ob sie am Ende eine h2, h3 oder h4 ziert. Mir persönlich ist allerdings wichtig, dass diese Klasse einem Überschriftenelement gegeben würde und keinem DIV oder SPAN.

Ich sehe in dem Vorteil auch eine Gefahr. Denn der Entwickler muss sich nur noch um die Verteilung von Klassen bemühen, wird aber auf der anderen Seite nicht zu einem vernünftigen HTML-Code angehalten. Was wird mit einer solchen Vorgehensweise gewonnen? Es bleiben nur noch Anpassungen an die Optik des jeweiligen Projekt übrig. Anpassungen an eine abweichende Struktur des Standard-Moduls sind nicht mehr notwendig.

Ich denke nicht, dass die damit einhergehende Zeitersparnis rechtfertigt, der Struktur einer Webseite weniger Beachtung zu geben. Webseiten sind nicht nur schöne Optik, sie bestehen auch aus einer sinnvollen Struktur. Beides sollte ein Frontendentwickler beherrschen und pflegen.

Eine Entkoppelung wird es nie geben

Eine Entkoppelung von HTML und CSS wird es nie geben, schliesslich ist CSS die Sprache, mit der eine HTML-Struktur gestaltet werden soll. Beide sind also miteinander verwoben. Der objektorientierte Ansatz scheint diese Verbindung so weit wie möglich verdrängen zu wollen. Die Abstraktion um der Abstraktion willen ist aber nicht zielführend. Sparsames, semantisches HTML sollte mit ebenso sparsamem und logisch durchdachtem CSS gestaltet werden.

Was alle objektorientierten Ansätze hingegen schaffen, ist eine Entkoppelung von Gestaltung (CSS) und semantischem HTML. Nimmt man vor allem BEM und OOCSS ernst, dann ist es egal, ob die Klasse .btn an einem Button ist (oder zumindest einem Link). Und genau dies sehen wir immer wieder bei JavaScript-zentrierten Webseiten. Da werden SPAN oder DIV mit der Klasse .btn versehen und mit ein wenig JavaScript zu Buttons verwandelt.

Eine Klassen-Abstraktion gerät irgendwann an ihre Grenzen. Der CSS-Zengarden hat uns zwar gezeigt, dass man eine identische HTML-Struktur sehr unterschiedlich gestalten kann. Aber der CSS-Zengarden war nie praxisnah. Er arbeitete mit einer einfachen Struktur, die zudem bewusst mit leeren Elementen und zusätzlichen Klassen ergänzt wurde, damit die jeweiligen Designer/Entwickler sich austoben konnten.

Wenn wir in der Praxis die Webseite einer Bank, eines Shops oder die eigene Webpräsenz neu gestalten, dann geht es doch normalerweise nicht nur um einen neuen Anstrich. Ich hatte in meiner beruflichen Laufbahn nur zwei Fälle, bei dem der Kunde bewusst nur die Optik verändern wollte. Im ersten Fall sollten die Templates nicht verändert werden. Im zweiten Fall konnten sie nicht verändert werden, weil die deutsche Niederlassung einer amerikanischen Firma keine Zugriffsrechte bekam. Aber das sind Ausnahmefälle.

Üblicherweise wird das komplette HTML neu erstellt. Denn es gibt nicht nur ein komplett neues Design, auch die Ansprache verändert sich oft, die Seitenstruktur ebenso. Das ist weder schlimm noch ungewöhnlich. Und da HTML und CSS miteinander verknüpft sind, bedeutet ein Relaunch immer eine Arbeit auf beiden Ebenen.

Wenn dann noch ein neues CMS eingeführt wird, kann es sein, dass die Arbeit noch umfangreicher wird. Schliesslich gibt es genügend Contentmanagementsysteme, die nicht nur den Inhalt verwalten (content managen), sondern auch eine eigene Struktur von sich aus ausgeben. So kann es sein, dass man mit CMS-eigenen Klassen, IDs und Strukturen arbeiten muss. Auch in diesem Falle ist also wieder eine Anpassung unserer Ansätze bei HTML und CSS notwendig.

Elemente dürfen direkt gestylt werden

Alle objektorientierten Ansätze propagieren die Verwendung von Klassen an Stelle normaler Elementselektoren. CSS bietet eine grosse Auswahl an Selektoren, doch diese werden bewusst negiert. Es wird eine größere Flexibilität in Aussicht gestellt, indem man sich vom existierenden HTML unabhängig macht.

Dabei kommen die meisten Elemente mit drei eingebauten Selektoren: dem Element selber, sowie mit den Pseudoelementen :before und :after. In Einzelfällen können auch Selektoren wie :first-child oder :nth-of-type(odd) weiterhelfen. Natürlich kann man sich mit zusätzlichen Klassen oder Elementen behelfen. Aber wenn uns doch diese Werkzeuge zur Verfügung stehen, warum sollten wir sie nicht nutzen?

Best Practices statt absoluter Abstraktion

Anstatt die Verwendung von CSS stark zu abstrahieren, sollten wir uns lieber um Best Practices kümmern, diese vereinheitlichen und möglichst breit kommunizieren. Dabei darf unsere Konzentration nicht auf CSS allein beruhen. Die andere Seite der Medaille ist weniger hübsch und spannend, gibt dem Ganzen aber einen Sinn: HTML. Nur mit einer gesunden HTML-Basis macht ein gutes CSS ein gutes Endprodukt.

Da Semantik etwas sehr individuelles ist, das sich nicht über alle möglichen Projekte hinweg abstrahieren lässt, kommt es weniger auf starre Regeln, als auf gute Beispiele an. Anhand dieser Beispiele kann man die eigene optimale Lösung finden, die auf das aktuelle Projekt passt.

Semantische Klassen

Die oft zitierten “semantischen Klassen” gibt es im Wortsinne nicht. Semantik wird durch HTML-Elemente repräsentiert. Klassen existieren als HTML-Attribute, damit man zusätzliche Ansatzpunkte für die Gestaltung einer Webseite schaffen kann. Sie sind also ganz bewusst Teile der Gestaltung, nicht der Semantik. Wir sprechen besser nicht von semantischen, sondern von pflegbaren Klassen.

Die Benennung einer Klasse nach visuellen Kriterien ist nicht falsch, sie ist allerdings unpraktisch. Ein Element mit der Klasse .rot steht in der Gefahr, dass es im Laufe des Projektes oder in einem Folgeprojekt blau oder schwarz formatiert wird. Eine Klasse .warnung ist da besser. Diese Klasse gibt keine optischen Informationen, sie informiert über die inhaltliche Aufgabe des betreffenden Elements. Sie ist dadurch auch lesbarer als .hinweis1. Aber sie ist natürlich festgelegt. Auch die beiden folgenden Beispiele sind unpraktisch und irreführend:

1 <h2 class="h3">Tolle Überschrift</h2>
2 <div class="h3">Ich möchte eine Überschrift sein!</di\
3 v>

Die Klasse h3 hat weder aus der Überschrift zweiten Grades noch aus dem DIV eine Überschrift dritten Grades gemacht. Der einzige Zweck dieser Klasse ist es, eine bestimmte Optik zu transportieren. Und die Erschaffer dieser Klasse sahen wohl in der Analogie zur Überschriftenhierarchie eine gute Möglichkeit, sich die konkrete Optik zu merken.

Der Klassiker in dieser Hinsicht sind Buttons:

1 <a class="btn" href="link.html">ein Link, wie ein But\
2 ton gestaltet</a>
3 <h4 class="btn">eine Überschrift, wie ein Button gest\
4 altet</h4>
5 <div class="btn">ein semantisches Nichts, wie ein But\
6 ton gestaltet</div>

Die allgemeine Vorstellung, wie ein Button auszusehen hat, wird mit der Klasse .btn transportiert. Hierbei ist es egal, ob diese Klasse an einem Link, einer Überschrift oder einem DIV hängt. Dies alles hat allerdings nichts mit Semantik zu tun. Die Optik wird stimmen, die semantische Bedeutung wird nicht transportiert. Das ist auch nicht die Aufgabe von CSS. Besonders tragisch ist dies im Falle der Buttons.

Vor allem bei JavaScript-zentrierten Projekten/Applikationen sehen wir immer wieder nachlässiges HTML. Da bekommen dann SPAN-Elemente oder Links die Optik von Buttons verpasst und wenn man Glück hat, hat der Entwickler mit ziemlich viel JavaScript noch dafür gesorgt, dass diese falsch genutzten Elemente sich so verhalten, als wären sie ein Button. Warum nicht einfach einen Button nutzen?

In meinen Augen fördert das Gerede von semantischen Klassen den Eindruck, man könne HTML ersetzen oder zumindest ignorieren. Aber für ein gutes Frontend-Projekt sind alle drei Bestandteile notwendig: HTML, CSS und JavaScript und zwar in dieser Reihenfolge.

Doch machen wir uns nichts vor: eine vollkommen neutrale Auszeichnung zu Gestaltungszwecken ist zwar möglich, aber nicht notwendig und auch nicht anzustreben. Wir verbinden doch schliesslich mit den Inhalten einen Sinn. Warum sollten wir diesen dann nicht auch in den Klassen wiederspiegeln lassen?

Klassen werden von Menschen für Menschen geschrieben. Weder eine Suchmaschine, noch ein Browser oder ein Screenreader haben einen Nutzen von der Verwendung oder gar der Benennung von Klassen. Deshalb sollten Klassennamen von Entwicklern verstanden werden, damit sie diese problemlos nutzen können. Denken Sie dabei auch immer an Entwickler, die Ihr Projekt übernehmen werden. Wie schwer machen Sie es denen, Ihren Code zu verstehen?

Die einzige Ausnahme zu dieser Regel sind die Mikroformate. Hierbei werden fest definierte Klassennamen an (hoffentlich) semantische Elemente gesetzt, um diesen eine zusätzliche Bedeutungsebene zu geben und sie maschinenlesbar zu machen. So kann man Adressen und Termine maschinenlesbar auszeichnen.

Mikroformate sind allerdings nicht primär zur Gestaltung von Webseiten gedacht. Diese Abhandlung dreht sich um die Gestaltung von Webseiten und die adäquate Benennung von Klassen. Meiner Meinung nach gehorcht die Vergabe von Klassen für Design anderen Gesetzen, als bei den Mikroformaten.

Unterschiedliche Arten zu stylen

Alle bisherigen Überlegungen zur Abfassung eines Stylesheets sollten in Betracht ziehen, wie am Ende das resultierende CSS genutzt wird. Werden Templates erstellt und quasi mit der Verteilung von Klassen eine gewünschte Gestaltung erreicht? Oder werden in den Templates nur wenige Klassen eingesetzt, da die GEstaltung über die direkte Modifikation des CSS geschieht?

Das sind zwei grundsätzlich verschiedene Ansätze. Den ersten Ansatz kann man “HTML-fokussiert” nennen. Er ist besonders praktisch, wenn man schnell einen Prototypen erstellen möchte oder den Templateentwicklern einen Baukasten zur Verfügung stellen will. Frameworks wie Bootstrap und Foundation arbeiten genau nach dieser Methode.

Sollten Sie also HTML-fokussiert arbeiten, kann es sinnvoll sein, mit vielen Modifikatoren zu arbeiten.

Im Kontrast dazu steht die “CSS-fokussierte” Entwicklung. Hier werden zwar auch Klassen im Template verteilt, die eigentliche Gestaltungsarbeit geschieht aber unabhängig davon im CSS. Der wesentliche Unterschied dürfte sein, dass in der CSS-fokussierten Entwicklung keine Notwendigkeit für eine Vielzahl globaler Helperklassen besteht. Soll ein Bild bspw. nach links floaten oder einen roten Rahmen haben, erledigt man dies im passenden Modul. Bei der HTML-fokussierten Entwicklung kann es dazu kommen, eine globale Helperklasse für diesen Zweck einzusetzen. Bootstrap 4 bietet eine Fülle solcher Klassen.

11. Mein modularer Ansatz

Die Grundphilosophie der objektorientierten Projekte gefällt mir. Denn sie wenden den Blick auf die Seitenbestandteile und verstehen eine Webseite als Addition einzelner Objekte. Mit einigen Details der Nomenklatur stehe ich allerdings auf Kriegsfuss. Insbesondere mit dem Ansatz, immer Klassen an Stelle von Elementen im CSS anzusprechen, kann ich mich nicht anfreunden.

Da erfahrungsgemäß nicht jeder Entwickler immer in der gleichen Art und Weise seine Projekte erarbeiten kann, gehe ich von einem gemeinsamen Blick auf die CSS-Entwicklung aus, der uns auf unterschiedlichen Wegen zum gleichen Ziel bringen kann: qualitativ gute, modulare Webseiten.

Meine Grundsätze bei der Entwicklung von Webseiten sind Folgende:

  • Im Zentrum meiner Arbeit stehen einzelne Module, keine kompletten Webseiten.
  • Die Module sind eigene kleine Universen.
  • Es gibt nur wenige globale Styles.
  • Es gibt eine Trennung zwischen Layout und Design.
  • Jedes Modul sollte ohne Probleme auch an einer anderen, sinnvollen Stelle des Layouts platziert werden können.
  • Elemente beeinflussen sich zwischen Modulen nicht.
  • Semantik ist und bleibt Teil des HTML. Es werden die für den Zweck passenden Elemente genutzt.
  • Zu Beginn des Projektes sollte man sich entscheiden, ob das Differenzieren von Designdetails im HTML-Code stattfinden kann oder nur über das CSS laufen soll.
  • IDs sind für exakt zwei Sachen gut: Formularelemente und wichtige Strukturbereiche des Layouts. Für Letztere schreibe ich sie auch möglicherweise in mein CSS.

Ich ergänze diese Grundregeln noch durch zwei persönliche Regeln:

  • Ein Framework hält mir lästige, immer wiederkehrende Probleme vom Hals: es definiert einen Basis-Codestil, ermöglicht die schnelle Lösung der grundlegenden Layoutaufgaben und bietet eine erste Dokumentation.
  • Ich nutze einen Präprozessor, damit ich effizient und modular arbeiten kann. Wenn ich es mir aussuchen kann, dann nutze ich Sass.

Wähle Deine Waffen weise

Ich bin immer wieder irritiert, wenn jemand postuliert, ich solle keine IDs oder Inline-Styles nutzen. Beides sind normale Bestandteile des CSS-Standards. Sie sind deshalb nicht per se besser oder schlechter, als Klassen oder ausgelagerte Styles. Es kommt immer auf den Einsatzzweck an. Wir müssen uns Gedanken über Vor- und Nachteile des eigenen CSS-Ansatzes machen. Und so kann es sein, dass wir zielgerichtet Inline-Styles nutzen, weil sie der sinnvollste, sicherste und schnellste Weg zur Zielerreichung sind.

Ich hatte vor Jahren in einem Projekt Teaser mit Hintergrundbildern umgesetzt. Diese Hintergrundbilder sollten von Redakteuren editiert werden können. Selbstverständlich kamen deshalb Inline-Styles zum Einsatz. Techniken müssen nicht immer zu 100% in einem Projekt genutzt werden. Manchmal sind sie punktuell hilfreich. Deshalb ist eine globale Verteufelung einzelner Techniken wenig sinnvoll.

Es ist aber auch wenig sinnvoll, seine komplette Webseite mit Inline-Styles zu versehen. Denn dann muss man immer die Templates modifizieren, wenn man an einem Style eine Änderung vornimmt. Und - noch viel wichtiger - kann man nicht vom Caching einer externen CSS-Datei profitieren. Zudem sind manche Techniken wie die Nutzung von Pseudoelementen mit Inline-Styles nicht möglich.

Einzelne HTML-Dateien

Wenn es mir das Projekt erlaubt, schreibe ich meinen Frontendcode in kleine HTML-Schnipsel, passend zu den kleinen Sass-Schnipseln. Ich konzentriere mich zuerst auf die Entwicklung der Module, indem ich sie innerhalb eines selbstentwickelten, schlichten Styleguides betrachte und kontrolliere. Erst in einem späteren Schritt entstehen ganze Seiten, in denen die einzelnen Module dann zusammen wirken. Auch hier arbeite ich selbstverständlich mit den Includes. Da ich meine Arbeit normalerweise an andere Entwickler weiterreiche, die mein HTML dann in Templates für ihr CMS überführen, verzichte ich auf die Nutzung einer Templatesprache. Das würde zu unnötigen Verständnisschwierigkeiten und Reibungsverlusten führen. Mittlerweile spiele ich allerdings mit dem Gedanken, Handlebars einzusetzen, um die Erstellung von Iterationen einzelner Module zu erleichtern.

Taskrunner

Vor einigen Jahren habe ich mir die Nutzung von Grunt angewöhnt. Es ist toll, welche Funktionsvielfalt ein solcher Taskrunner bietet. Immer wieder ergänze und überarbeite ich mein bisheriges Setup. Ich versuche mich dabei aber zu beschränken, denn man kann sich sehr schnell vor lauter Begeisterung in der Arbeit mit Grunt verlieren.

Ein mir sehr wichtiger Task ist dabei php2html. Mit dessen Hilfe werden alle meine kleinen PHP-Dateien, die ich zum Testen und zur Demonstration entwickelt habe, in HTML-Dateien umgewandelt. Diese kann ich dann an Kunden und Kollegen weitergeben, denn nicht jeder hat ganz selbstverständlich einen Webserver auf dem eigenen Rechener laufen oder weiss damit umzugehen. Für ein Projekt, bei dem keine dynamischen Inhalte erstellt oder nachgeladen werden müssen, ist die Auslieferung reiner HTML-Dateien viel sinnvoller, als den PHP-Interpreter zu nutzen.

Schnipsel im CSS dank Präprozessoren

CSS zu programmieren war schon lange der Wunsch vieler Entwickler. Präprozessoren eröffnen diese Möglichkeit. Sie ermöglichen zudem, ein Stylesheet in viele kleine Einzeldateien zu unterteilen und für die Ausgabe einer einzigen Datei zu importieren. Dieser Prozess läuft nur in der eigenen Entwicklungsumgebung ab und birgt deshalb nicht die sonst zu erwartenden Performancenachteile einer Aufsplittung von CSS in viele Einzelteile.

Es gibt ein paar unterschiedliche Präprozessoren. Neben dem Platzhirsch Sass gibt es im Wesentlichen noch LESS und Stylus. Aber auch PostCSS kann man so nutzen, dass die vorgenannten komplett ersetzt werden. Die grundlegenden Vorgehensweisen und Erkenntnisse gelten für alle Projekte. Sie unterscheiden sich in Details der Syntax und in wenigen Fähigkeiten. Ich konzentriere mich im Weiteren auf Sass.

Variablen

Variablen sind der schnellste Nutzen, den man aus der Verwendung von Präprozessoren ziehen kann. Die Auslagerung designrelevanter Details wie Farben, Abstände, Schriftarten und -größen ermöglicht es uns, sehr schnell eine Modifikation des gesamten Auftrittes vorzunehmen. So sind kleine Designanpassungen oder gar Themes in Windeseile realisiert.

Aufteilung des CSS in viele einzelne Module

Ich nutze Sass im Wesentlichen, um mein CSS so optimal und effizient wie möglich modularisieren und abstrahieren zu können. Das tue ich bspw. indem ich nicht an einer großen, sondern an vielen kleinen, spezialisierten CSS-Dateien arbeite. Diese importiere ich dann in eine zentrale Datei, die dann wiederum von Sass in eine CSS-Datei gewandelt wird. In dieser zentralen SCSS-Datei stehen idealerweise nur Verweise auf importierte Modul- sowie Konfigurationsdateien.

Durch die starke Modularisierung - jedem Modul eine eigene Datei - kann ich einzelne Bestandteile eines Projektes wiederverwenden. Diese vielen kleinen Einzelteile machen es auch einfacher, im Team an einem gemeinsamen CSS zu arbeiten. Jeder Entwickler bekommt seine Modul-Datei(en) zugewiesen und kommt dadurch den Kollegen nicht in die Quere.

Ich versuche bei der Aufteilung der Dateien, jedem Modul seine eigene SCSS-Datei zu geben. Ich gebe der SCSS-Datei dann den Namen des Moduls. Darüber hinaus werden die Regeln für das Layout in eine eigene SCSS-Datei gepackt. Ich erstelle keine Dateien für einzelne Breakpoints, wenn ich eine responsive Seite erstelle. Stattdessen schreibe ich die notwendigen Mediaqueries immer an den Teil des Moduls, der verändert werden soll. Das erleichtert mir die Suche beim Debuggen oder bei einer notwendigen Veränderung.

Die Zuweisung von Mediaqueries geschieht dabei über ein kleines Mixin, das mir Schreibarbeit wegnimmt. Zudem lagere ich die Werte der Breakpoints als Variablen aus. Sie können somit zentral angepasst werden.

 1 // Das Mediaquery-Mixin
 2 
 3 @mixin mq($dimension, $breakpoint, $breakpoint2:false\
 4 ) {
 5     @if $dimension == min {
 6 		@media screen and (min-width: $breakpoint) {
 7 			@content;
 8 		}
 9 	} @else if $dimension == max {
10 		@media screen and (max-width: $breakpoint) {
11 			@content;
12 		}
13 	} @else if $dimension == min-max {
14 		@media screen and (min-width: $breakpoint) and (max\
15 -width: $breakpoint2) {
16 			@content;
17 		}
18 	}
19 }

Beispiel einer Verzeichnisstruktur

In meinem Sass-Ordner befinden sich grundsätzlich folgende Elemente:

 1 sass/
 2   _config.scss
 3   _modules.scss
 4   _mixins.scss
 5 
 6   config/
 7     _colors.scss
 8     _mediaqueries.scss
 9     _modules.scss
10     _project-basics.scss
11 
12   mixins/
13     _forms.scss
14     _helpers.scss
15     _lists.scss
16     _mediaqueries.scss
17     _navigation.scss
18 
19   modules/
20     _fonts.scss
21     _forms.scss
22     _helpers.scss
23     _layout.scss
24     _lists.scss
25     _navigations.scss
26     _normalize.scss
27     _page-footer.scss
28     _typography.scss
29     fonts/
30       _svg-icons.scss
31     forms/
32       _buttons.scss
33       _form-cnt.scss
34       _text.scss
35     lists/
36     navigations/
37       _breadcrumb.scss
38       _main-navigation.scss
39 
40   styles.scss
  1. Es gibt eine styles.css, deren Inhalt von Projekt zu Projekt identisch bleiben kann, da darin nur Dateien importiert werden, die ihrerseits wieder Dateien importieren: _config.scss, _modules.scss und _mixins.scss.
  2. Ein Ordner mit Mixins. Sollten diese aus unterschiedlichen Quellen kommen, werden sie in Ordnern separiert. Platzhalter habe ich mittlerweile abgeschafft. Früher waren sie auch in diesem Ordner. Alle Mixins werden in der Datei _mixins.scss importiert.
  3. Der Ordner modules enthält alle Module. Darin platziere ich auch eventuelle Framework-Dateien, die ich modifiziere. Das Framework selber soll in seinem Ordner unverändert bleiben, damit ein Update ohne größere Nebeneffekte möglich ist. Die Benennung der Moduldateien sollte im Wesentlichen selbsterklärend sein. In Dateien wie _layout.scss und _helpers.scss sind allgemeine Regeln gesammelt. Dateien für konkrete Module werden möglichst mit deren Klassennamen benannt(z.B. _page-footer.scss).
  4. Auch im Ordner modules können sich Unterordner befinden. Deren Inhalte werden dann in einer Datei importiert. Die Datei modules/_lists.scss importiert also alle Inhalte aus dem Ordner modules/lists/.

Insbesondere der letzte Schritt, Dateien aus Unterordnern noch einmal in einer speziellen Datei zu importieren, erscheint Ihnen vielleicht übertrieben. Ich sehe darin den Vorteil, einen schnelleren Überblick zu bekommen. Bei der Suche nach importierten Listen-Dateien werde ich nicht von Dateien anderer Art abgelenkt. Aber grundsätzlich können Sie natürlich alle Module in der _modules.scss oder gar der styles.scss importieren. Ich bevorzuge den auf den ersten Blick umständlicheren Weg.

Module erstellen

In einem ersten Schritt identifiziere ich gleichartige Module innerhalb eines Projektes. Das funktioniert natürlich dann besonders gut, wenn das Design schon mehr oder weniger fertig vorliegt. Doch eigentlich ist dieses alte Vorgehen, dass der Frontendentwickler die Brocken vom Designer zwecks Umsetzung hingeworfen bekommt, nicht mehr zeitgemäß. Angesichts der Notwendigkeit responsiver Umsetzung müssen Design und Frontendentwicklung vielmehr parallel laufen. Und so kann es passieren, dass zusätzliche Iterationen zu einem schon existierneden Modul hinzukommen.

Da ich mich in solchen Situationen auch schon hin und wieder über meine eigenen Entscheidungen geärgert habe, versuche ich nun mittlerweile, vorsichtiger vorzugehen:

  1. Klassennamen sollten relativ abstrakt sein. Zu konkrete Funktionszuweisungen können stören, wenn das gleiche oder ein ähnlich aussehendes Modul in einem anderen Sinnzusammenhang benutzt wird.
  2. Die Inhalte von Modulen sollten sich ändern können, ohne dass es das Modul beschädigt. Ein Teasercontainer muss mit einem Video, einem Suchfeld oder einer Liste bestückt werden können.
  3. Manchmal muss man mutig entscheiden, das prinzipiell gleiche Modul doppelt vorzuhalten. Insbesondere bei Suchfeldern für unterschiedliche Zwecke, die evtl. manchmal per JavaScript erweitert werden.

Ein konkretes Beispiel für den ersten Punkt hatte ich in einem Projekt, in dem ich dachte, alle Inhaltsmodule schon zu kennen. In diesem Projekt gab es bislang ein Selectfeld und das war ein Sonderfall, da es mittels “typeahead” dynamisiert wurde. Das JavaScript vergab selber viele Klassen, sodass ich keine eigene mehr ausdenken musste.

Als dann die Anforderung für zwei Selectfelder zur Auswahl von Datum bzw. Zeit kam, schrieb ich alle Styles der Klasse .date-time zu. Ich dachte schliesslich, es gäbe keine weiteren Selectfelder. Nach ein oder zwei Wochen wurde ich eines besseren belehrt. Nun sollte auch die Auswahl von alternativen Adressen in einem Selectfeld abgehandelt werden. Das Styling sollte dem von Datum und Zeit gleichen. Glücklicherweise nahm der Entwickler, der meine Module in eine Angular-Applikation implementierte, die Änderung der Klasse leicht. Es war trotzdem ein Zeichen, dass ich nicht gut genug nachgedacht hatte. Von Anfang hätte hätte die Klasse abstrakter lauten müssen, bspw. .select. Damit wäre Klasse unabhängig vom Inhalt geblieben. In diesem konkreten Falle wäre es auch ein hilfreicher Hinweis gewesen, welches Element gerade neu gestaltet wird.

Kapselung der Module für sich selber

Namen für Module zu finden ist schwer. Sie sollten abstrakt genug sein, dass sie frei für unterschiedlichste Inhalte verwedent werden können. Abstrakte Varianten wie .box-1 und .box-2 sind aber auch schwer zu nutzen, denn ohne eine häufige Referenz auf eine Art Dokumentation benötigt man für die Anwendung der Klassen ein prima Gedächtnis.

Der Name des Moduls sollte auch der Name der SCSS-Datei sein, ebenso der Name der Include-Datei (HTML). Im CSS sollte vor dem Namen des Moduls nichts stehen. Das Modul steht für sich allein und ist dadurch transportabel. Es kann allerdings Situationen geben, in denen es geboten ist, diese eiserne Regel aufzubrechen. Ein Beispiel:

Für ein Projekt gibt es einheitliche Stile für Buttons. Die großen Buttons werden überall auf der mobilen Seite genutzt. Über sie gelangt man von Seite zu Seite der Applikation. Es gibt insgesamt sechs verschiedene Seitentypen, die sich unterschiedlichen Abständen der Inhalte zu den Browserrändern niederschlagen. Auf mindestens einer dieser Seitentypen hat der große Button einen größeren horizontalen Margin, als sonst. Und dieser unterscheidet sich zudem von den anderen Elementen auf diesem Seitentyp.

Wollte man der bisher propagierten eisernen Regel folgen, müsste man mit einem Modifikator dafür sorgen, dass der Browser eine geringere Breite oder größere horizontale Margins besitzt.

Zur Unterscheidung haben wir aber schon einen Ansatzpunkt: den “Seitentyp”. Er schlägt sich in einer Klasse auf einem Elternelement des Buttons nieder. Anstatt nun also den Button direkt zu formatieren, kann man die kleine Abweichung auch in Abhängigkeit zur Existenz auf einem Seitentypen machen. Je nachdem, was für das eigenen Templating passender ist.

In solchen Fällen sollte es sich aber immer um eng begrenzte Modifikationen handeln. Es gilt die gleiche Regel, wie bei Modifikatoren: möglichst nur eine Eigenschaftsdimension verändern.

Module auszeichnen

Als BEM bekannt wurde sträubte sich in mir alles, diese Methodologie zu nutzen. Schliesslich kann BEM in sehr langen Klassennamen resultieren. Mit der Zeit und mit der notwendigen Praxis haben sich meine Befürchtungen gegeben. Ich empfinde BEM noch immer nicht als “schön”, ich sehe aber meine Aufgabe auch nicht darin, schönen Code zu schreiben. Er soll vielmehr wartbar und für andere lesbar sein. Das wiederum bietet mir BEM. Mir sind dabei aber zwei Aspekte wichtig:

  1. Wenn es eine zwingend einfache HTML-Struktur gibt (unverschachtelte Listen und Tabellen), dann verzichte ich darauf, jedem Element eine Klasse zu geben. Elementselektoren wurden genau für diesen Zweck erfunden.
  2. Es gibt keine “Enkel”-Selektoren, nur eine 1:1-Beziehung zwischen dem Element und dem Modul.

Den ersten Aspekt hatte ich schon früher thematisiert. Als Beispiel dienten mir Naviagtionen. Einfache Navigationen würden von mir nur eine Klasse als Modul bekommen, die einzelnen Bestandteile würden über Elementselektoren gestaltet werden. Dadurch ist das HTML schlank. Kommen Subnavigationen hinzu, wird das CSS komplexer und zusätzliche Klasse kommen ins HTML. Das ist dem Anlass angemessen.

Den zweiten Aspekt möchte ich im Folgenden illustrieren. Nehmen wir uns beispielhaft einen Teaser vor:

 1 <div class="teaser">
 2   <header class="teaser__headercontainer">
 3     <h3 class="teaser__headercontainer__header">Übers\
 4 chrift</h3>
 5   </header>
 6   <div class="teaser__content">
 7     <p class="teaser__content__paragraph">Lorem Dinge\
 8 nskirchen und so weiter, ihr wisst schon ....</p>
 9   </div>
10   <footer class="teaser__footer">
11     <a href="linkziel.html" class="teaser__footerlink\
12 ">weiterlesen ...</a>
13   </footer>
14 </div>

Das Headerelement innerhalb des Teasers ist optional. Auf den ersten Blick ist es nicht notwendig. Möglicherweise erfüllt es seine Dienste, um Designdetails zu ermöglichen. Es kann also sein, dass eine zukünftige Iteration dieses Teasers (in einem anderen Projekt) ohne das Headerleement auskommen kann. Die Klasse am Überschriftenelement impliziert aber geradezu die Existenz dieses Headerelements. Durch die Benamung wird eine Struktur reflektiert. Exakt dies sollte durch BEM ja aufgelöst werden. Also sollten wir niemals “Enkelelemente” mit BEM erschaffen. Die korrekte Klasse wäre .teaser__header.

Auch der Absatz innerhalb von .teaser__content krankt an diesem Problem. Hinzu kommt, dass die Inhalte möglicherweise über einen Editor von einem Redakteur gepflegt werden sollen. Dies bedeutet natürlich, dass auch andere Inhalte als nur Absätze eingegeben werden könnten. Deshalb sollten für die Inhalte von .teaser__content nur Elementselektoren im CSS zum Einsatz kommen. So verhindern Sie, dass die Redakteure Klassen an Elemente fügen müssen.

Im Falle des Footers wird die korrekte Lösung deutlich. Der weiterführende Link bezieht sich in der Klassenbenamung nur auf das Modul und nicht auf seine konkrete Umgebung. Es wird uns dadurch ermöglicht, die Struktur zu verändern, ohne das Styling des Links zu beeinträchtigen. Die bessere Strultur sähe aöso folgendermaßen aus:

 1 <div class="teaser">
 2   <header class="teaser__headercontainer">
 3     <h3 class="teaser__header">Überschrift</h3>
 4   </header>
 5   <div class="teaser__content">
 6     <p>Lorem Dingenskirchen und so weiter, ihr wisst \
 7 schon ....</p>
 8   </div>
 9   <footer class="teaser__footer">
10     <a href="linkziel.html" class="teaser__footerlink\
11 ">weiterlesen ...</a>
12   </footer>
13 </div>

Ein System erarbeiten, das alle intuitiv verstehen

Alle Systeme und Handlungsempfehlungen sind nur dann gut, wenn sie vom Entwickler verstanden und akzeptiert werden. Sie müssen in Fleisch und Blut übergehen können, damit keine Fehler und keine unnötigen Zeitverzögerungen entstehen. Bei der Arbeit im Team ist es zudem wichtig, dass sich alle an diese Spielregeln halten.

Sowohl für Einzelkämpfer als auch für ein Team sollten folgende Punkte geklärt und abgestimmt werden:

  1. Welche einheitlichen Benamungsregeln sollen gelten?
  2. Soll ein Namespace genutzt werden?
  3. Wie soll der Code eingerückt werden? (Eine Zeile oder mehrere?)
  4. Wie oft soll ins Versionierungssystem committet werden?
  5. Kommentare auf alle Fälle, aber wie und was?
  6. In welcher Sprache sollen Klassennamen und Kommentare verfasst sein?

Meine Antwortvorschläge sind folgende:

zu 1.: Ich empfehle BEM. Je nach Teamzusammensetzung nehmen Sie die ursprüngliche, strikte Version oder eine etwas aufgeweichte. Ich habe meine Gründe dafür oben beschrieben. Ich bevorzuge BEM, weil es einfach ist. Die Klassen müssen nicht zusätzlich kategorisiert werden (Base, Module, Theme usw.). Und es ist eine Art Industriestandard. Wenn neue Entwickler zum Team stossen ist es wahrscheinlicher, dass diese schonmal mit BEM gearbeitet haben, als mit SMACSS oder einer selbst ausgedachten Variante.

zu 2.: Namespaces sind dann hilfreich, wenn man mit einem Framework arbeitet oder die Arbeit anderer ergänzt. Sie verhindern ungewollte Kollisionen. Wenn sie genutzt werden, sollten sie sehr kurz sein. Am Besten nur zwei Buchstaben, gefolgt von einem Minuszeichen.

zu 3.: Ich habe früher versucht, eine Regel immer in einen Zeile zu schreiben. Bei breiten Monitoren ist das nicht schwierig. Darunter leidet allerdings die Übersichtlichkeit. Zudem ist es bei der Nutzung von Versionierungssystemen sinnvoll, jede Eigenschaft in eine eigene Zeile zu schreiben. So sieht man später bei einem Diff die wahren Unterschiede schneller auf einen Blick.

zu 4.: Ich committe oft. Ich committe immer, wenn ich eine Aufgabe abgearbeitet habe. Ich achte dabei nicht auf Fehlerfreiheit. Die kann man oft erst sehr viel später feststellen. Aber wenn ich bspw. ein Suchfeld erstellt habe, ein eigenes Modul also, dann committe ich dies. Idealerweise hat dieses Modul ein eigenes Ticket, das ich dann an den Anfang der Commit-Nachricht schreibe. Mein Commit geht primär lokal. Nicht jeder kleine Commit muss dann auch ins allgemeine Repo übertragen werden. Das kann auch später erst gesammelt geschehen.

zu 5.: Ich schreibe Kommentare immer dann in den Code, wenn ich den Eindruck habe, etwas erklären zu müssen. Die Zielperson bin ich selber in naher Zukunft aber logischerweise auch meine Kollegen oder noch unbekannte Personen. Eventuell genutzte Tricks dokumentiere ich, indem ich den Link zum Artikel in einen Kommentar schreibe. Ansonsten gerne auch Hinweise, wann eine bestimmte Klasse genutzt wird. Aber niemals Dokumentationen von HTML-Strukturen. In Mixins dokumentiere ich manchmal die Anwendung desselben im CSS. Ich nutze dabei immer den doppelten Slash als Kommentarzeichen, da diese von Sass nicht ausgegeben werden. Und Kommentare sind nur für Entwickler gedacht. Sie haben im produktiven CSS nichts verloren.

zu 6.: Klassennamen und IDs sollten in Englisch verfasst sein. Sollte man Hilfe benötigen und sich an Stackoverflow wenden, helfen deutsche Klassennamen nicht viel. Englisch ist zudem kompakter und hat keine Umlaute. Ich gestehe aber ein, dass es mir schwer fällt, diesen Grundsatz über das ganze Projekt durchzuhalten.

Arbeit in einer Pattern Library

Wie ich oben schon erwähnte, habe ich in letzter Zeit meine Module isoliert in einer Art Pattern Library erschaffen. Oft wird in diesem Zusammenhang auch von Styleguides gesprochen.

Nachdem alle bislang existierenden Applikationen mir aus unterschiedlichen Gründen nicht gefielen bzw. nicht in meine Arbeitsweise passten, baute ich mir meine eigene Pattern Library. Sie soll für mich nur dreierlei können:

  1. Die Module werden untereinander nach Typ auf eigenen Seiten sortiert. So habe ich bspw. alle Formulare oder Tabellen auf eigenen Seiten und sehe sofort, wenn es Konflikte zwischen Styles gibt.
  2. Der HTML-Code des jeweiligen Moduls soll dargestellt werden. Zusätzlich dazu verzeichne ich noch den Pfad zum passenden Include, falls mein Kunde mit meinen Quelldateien arbeitet.
  3. Es gibt optionale Notizen, die den Einsatz des HTML bzw. die Eigenheiten des CSS näher erläutern können.

Einer der Ausgangspunkte für meine Eigenentwicklung war Paul Robert Lloyds Pattern Primer. Für künftige Projekte überlege ich, meinen Workflow so zu verändern, dass ich mit Fractal oder Brad Frosts Style Guide Guide arbeiten kann.

Durch die Arbeit innerhalb einer solchen Pattern Library fokussiere ich mich auf das jeweilige Modul. Ich empfinde diese Arbeit als sehr effizient. Vor einigen Jahren war ich für das Frontend eines großen Schweizer Shops zuständig. Bis auf die Startseite, die wie immer eine Insellösung ist, habe ich alle zur Diskussion stehenden Unterseiten - etwa 20 - erst ganz zum Schluss erstellt. Dafür kombinierte ich dann die jeweiligen Grundlayouts mit den erstellten Modulen. Innerhalb kurzer Zeit waren viele Beispielseiten erstellt. Die einzelnen Module hingegen entwickelte ich ausschliesslich innerhalb meiner Pattern Library.

Da meine Arbeit normalerweise darin besteht, Backend-Entwicklern zuzuarbeiten und nicht selber an CMS-Templates zu schrauben, ist die Arbeit an einer separaten Pattern Library möglich. Die Backendentwickler nehmen sich meine beispielhaft entwickelten HTML-Schnipsel und überführen sie in Templates für ihr CMS. Eine Pattern Library kann aber selbstverständlich auch innerhalb eines CMS entstehen.

Eine tolle Übersicht über Styleguides und Pattern Libraries bietet styleguides.io. Dort findet man Tools, konkrete Beispiele und Artikel. Es lohnt sich, dort zu schmökern.

Lösung und Problem gleichermassen

Ich empfinde die Arbeit mit einer Pattern Library als große Hilfe und Erleichterung. Sie erlaubt mir die Konzentration auf die jeweiligen Module. Eine solche Arbeitsweise ist aber nicht die ideale Lösung für alle Beteiligten:

  • Es ist nicht einfach, sich ein solches Modul im Kontext einer gesamten Seite vorzustellen.
  • Designer ohne gute Kenntnisse in HTML und CSS werden Schwierigkeiten haben, ein neues Modul als schlichte Iteration eines bestehenden oder als konkrete Neuentwicklung einzustufen.
  • Prototyping mit den bestehenden Modulen ist nur für Projektbeteiligte möglich, die sich gut mit der verwendeten Templatingtechnologie auskennen (oder bspw. mit Includes in PHP).

Ein Pattern Library kann man mit gutem Willen und ein wenig Arbeit zu einem echten Styleguide ausbauen. Denn wenn man dies nicht schon selber getan hat, fehlen zu den Modulen im Wesentlichen noch Übersichten über verwendete Farben, Schriften und Icons. Ein Styleguide in HTML hat den Vorteil, dass er im Zielmedium existiert. Die bisherigen PDF-Versionen sind vor allem hübsch. Hilfreich wären sie aber eher als HTML-Version.

12. Fazit und Ausblick

Ich bin der festen Überzeugung, dass die modulare Entwicklung von Webfrontends der einzig vernünftige Weg ist, mit der steigenden Komplexität unseres Jobs umzugehen. Module ermöglichen uns bspw. die arbeitsteilige Entwicklung von Applikationen und Webseiten. In einem Projekt habe ich die einzelnen Module für die Webapp des Kunden erstellt. Dort nahm man diese Module und dynamisierte sie mit Angular.

Module ermöglichen uns auch eine einfache Dokumentation unserer Arbeit. Dabei müssen keine Screenshots gemacht werden und mit allen Modulen kann interagiert werden. Zudem werden alle Module mit eventuell browserspezifischen Besonderheiten dargestellt. All das ist ein großer Vorteil gegenüber den traditionellen PDF-Styleguides.

Zudem ist eine konsequente modulare Entwicklung auch für Agenturen sinnvoll. Sie können sich dadurch ihren eigenen Modulkatalog erstellen, aus denen Designer sich bedienen können. Rapid Prototyping lässt sich dadurch schnell realisieren. Im Prinzip kann jeder sein eigenes “Bootstrap” erstellen.

Ich habe versucht, Ihnen eine Orientierungshilfe zu erstellen. Sie ist keine fertige Blaupause. Sie müssen die Ideen und Anregungen in Ihren eigenen Workflow einbauen. Wichtig ist vor allem die Kommunikation zwischen den Gewerken und mit dem Kunden. Ein Styleguide ist nur dann nützlich, wenn er auch genutzt wird, wenn sich jeder gerne auf ihn bezieht. Jede Form des Styleguides hat genau da ihre Schwächen. Und ich fürchte, wir werden sie nie beseitigen können. Denn ein traditioneller PDF-Styleguide mag für Designer und Kunden attraktiv aussehen, für Entwickler ist er nicht besonders hilfreich. Schliesslich kann man keinen Code direkt heruaskopieren und man sieht kein browserspezifisches Verhalten oder Optiveränderungen in verschiedenen Breiten.

Ein Living Styleguide hingegen mag keine leckere Hochglanzbroschüre sein. Er ist aber genau im Zielmedium lokalisiert und sollte deshab für alle Beteiligten die richtige Art sein, die Arbeit anzugehen. Ich hoffe, Ihnen auf dem Weg dahin die richtigen Argumente geliefert zu haben.