Über unsMediaKontaktImpressum
Jens Grochtdreis 09. Februar 2016

Modulare Webentwicklung mit Sass

Webseiten sind keine monolithischen Gebilde. Es sind Systeme von Einzelteilen, die zusammengesetzt werden. Sie gleichen eher einem Gegenstand aus Lego, als einem Gemälde. Deshalb ist modulares Denken bei der Gestaltung und Entwicklung einer Webseite wichtig.

Im Bereich der Backendentwicklung ist dieses Denken schon Gang und Gäbe. Nicht nur ist OOP in allen Programiersprachen mittlerweile der Standard. Auch Frontend-Templates werden normalerweise in CM-Systemen in Einzelteilen abgelegt. Diese kleinen Templateschnipsel erzeugen dann wiederum bspw. eine FAQ oder einen Teaser. Selbst seitenorientierte CM-Systeme wie Wordpress kennen einzelne Module, die zu Templates hinzugefügt werden können.

Modulare Entwicklung ist auch im Frontend von hohem Nutzen. Seiten können ohne Probleme individuell zusammengestellt werden, wenn man dafür gesorgt hat, dass alle Module korrekt geschrieben wurden. Und die einzelnen Module sind zwischen Projekten transportierbar. So kann ein eigenes "Bootstrap" entstehen. Schliesslich erfinden wir mit jedem Projekt nicht das Webdesign neu, sondern verwenden immer wieder gleichartige Module, die sich primär durch optische Details unterscheiden. Im Weiteren werde ich einen Blick auf die modulare Entwicklung im Frontend werfen.

Modultypen im Frontend

Webseiten bestehen u. a. aus Modulen, die sich auf allen Seiten wiederholen, bspw. Header und Footer. Zudem gibt es Module, die typisch für bestimmte Seitentypen sind, beispielsweise Karusselle oder große, bildschirmbreite Bilder, sogenannte Hero-Bilder. Es gibt unterschiedliche Formen von Teasern, Linklisten oder Contentflächen. Dabei ist es nicht entscheidend, dass die Module identisch aussehen. Ihre Semantik sollte identisch sein. Die Modifikation der Optik kommt in einem zweiten Schritt.

Nehmen wir die beiden Container aus Abb.1.: Beide unterscheiden sich durch die Ausrichtung des Bildes und durch die Hintergrundfarbe. Aber grundsätzlich sind diese Container gleich. Deshalb beruhen sie auf dem gleichen Template.

<div class="media">
  <h2 class="media-headline">Headline</h2>
  <div class="media-content clearfix">
    <img class="media-img" src="" alt="">
    <p></p>
  </div>
</div>
<div class="media right-image bgcol1">
  <h2 class="media-headline">Headline</h2>
  <div class="media-content clearfix">
    <img class="media-img" src="" alt="">
    <p></p>
  </div>
</div>

In meinem Beispiel habe ich nur jeweils eine Klasse zur Modifikation der Hintergrundfarbe und der Bildausrichtung dem zweiten Container mitgegeben. Für solche "Modifikatoren" ist es hilfreich, nicht zuviele Änderungen in eine Klasse zu packen. Konzentrieren sich die Modifikatoren auf eine Änderung, ist ihre Anwendung flexibler. Keine Angst: Sie können locker 250 Klassen auf ein Element setzen. Bevor der Browser das nicht mehr mitmacht, haben Sie allerdings den Überblick verloren. Aber bis zu zehn Klassen auf einem Element sollten zu handhaben sein.

Übrigens: eine weitere Modifikation dieses Moduls könnte sein, das Bild wegzulassen. Es hat sich dann an der grundsätzlichen Art des Moduls nichts geändert.

Man kann sogar so weit gehen, jeglichen Container mit Headline und Inhalt als ein Modul zu verstehen. Dann wären auch Listen im Inhaltsberiech möglich, mehrere Absätze und/ oder mehrere Bilder oder gar ein Video.

Eine gute Planung am Beginn eines Projektes und eine große Flexibilität im Denken kann Ihnen dabei helfen, die richtigen Basismodule zu identifizieren, die Sie dann durch Modifikatoren erweitern.

Ein eigenes Bootstrap

Die bekannten UI-Frameworks Bootstrap [1] und Foundation [2] sind gute Beispiele für modulare Webentwicklung. Die einzelnen UI-Elemente werden in den Dokumentationen aus dem Zusammenhang gerissen dargestellt. Und sie funktionieren trotzdem sehr gut.

Viele Entwickler sind reserviert gegenüber solch fertigen Frameworks. Dabei sehen sie nicht, dass diese Frameworks intelligent strukturiert und geschrieben sind. Mit ein wenig eigenem Zutun kann man mit ihrer Nutzung eine sehr gute Codebasis erstellen. Diese wäre meist besser als die eigene.

Das mittelfristige Ziel modularer Entwicklung sollte deshalb sein, ein eigenes Bootstrap zu erstellen. Gerade in Agenturen liegen genügend Module aus vergangenen Projekten vor, die in einem solchen eigenen Framework zusammengefasst werden können. Doch dazu müssen die Module korrekt geschrieben sein. Es gibt einen einfachen Test, um herauszufinden, ob das CSS für ein Modul verbessert werden muss: platzieren Sie das Modul in ein völlig anders geschriebenes Layout, das möglichst einfach gehalten ist und das keine von einem anderen Projekt bekannten Klassennamen hat. Machen Sie bspw. aus .row ein .test-row. Oder packen Sie die Hauptnavigation in den Footer. Wenn Sie alles richtig gemacht haben, ist die Optik Ihrer Module erhalten geblieben.

Ein eigenes Universum

Jedes Modul steht für sich, ist sein eigenes Universum. Sie sollten auf Abhängigkeiten im CSS achten, die aufgelöst werden müssen. Schauen Sie sich beispielhaft diese beiden Codevarianten an:

/* --------- So macht man das! ------------ */
/* Das Modul steht für sich. */
.videowrapper {
  /*  Eigenschaften */
}
.videowrapper iframe {
  /* Eigenschaften */
}
/* ----------- keine gute Idee! ------------ */
/* Was, wenn der Videowrapper demnächst in einem
   anders benamten Container stecken sollte? */

.maincnt .videowrapper {
  /*  Eigenschaften */
}
.maincnt .videowrapper iframe {
  /* Eigenschaften */
}

Im zweiten Beispiel steht .videowrapper in Abhängigkeit der Klasse .maincnt. Der Frontendentwickler muss bei dieser Version also eine konkret benamte Struktur sicherstellen. Das schränkt die Wiederverwertbarkeit des Moduls eindeutig ein.

Es mag Einzelfälle geben, in denen die Abhängigkeit eines Moduls von der Existenz innerhalb eines anderen Containers wichtig ist. Der Normalfall ist dies nicht. Deshalb sollten Module so geschrieben werden, dass sie in jegliche Struktur passen.

Layout und Module separieren

Der erste Schritt für modulare Frontendentwicklung ist, zwischen den Modulen und dem Layout eine Trennung herbeizuführen. Das Layout ist nichts anderes, als die Verteilung der Inhalte innerhalb eines Browserfensters. Das geschieht meist in Form von Floats, die ein Grid bilden.

In diese Layoutflächen hinein werden dann die Module platziert. Es herrscht so eine strikte Trennung zwischen den Inhalten/Modulen und dem Layout, also der Verteilung derselben. Niemals sollte man deshalb eine Klasse für ein Modul mit einer Layoutklasse kombinieren, wie in diesem Beispiel:

<div class="teaser span-3of-12">
  <header class="teaser__header">...</header>
  ...
</div>

Mit der oben skizzierten Verzahnung von Modul und Layout ist das Modul nicht mehr transportabel. Es ist einfacher, handlicher und verständlicher, wenn man in der Umsetzung der Seite erst das grobe Layoutraster aufbaut und in dieses dann als neue Elemente die einzelnen Module, sprich die Inhalte integriert.

Module separieren

Arbeitet man mit einem CMS, bekommen alle Module eigene kleine Templates und sind somit voneinander separiert. Dies kann man auch schon während des Entwurfsprozesses machen, sollte man diesen außerhalb des CMS bewältigen. Auch in einem statischen Klickdummy sollte jedes Modul eine einzelne Datei sein, die am Ende in eine Seite inkludiert wird, auf die zusätzlich ein definiertes Template angewendet wird. All dies natürlich in der serverseitigen Skriptsprache der eigenen Wahl.

Diese Modularität kann auch für das notwendige CSS realisiert werden. Zum einen kann man einzelne CSS-Dateien erstellen, die in eine zentrale CSS-Datei importiert werden. Für den Livegang muss allerdings sichergestellt werden, dass die CSS-Dateien zu einer einzigen zusammengefasst (konkatiniert) werden. Denn der Import eines CSS ist eine Performancebremse. Importiert man sogar viele CSS-Dateien, so ist die Performancebremse umso größer. Zum anderen kann man einen Präprozessor nutzen. Dieser gibt am Ende eine CSS-Datei aus, auch wenn die Arbeitsgrundlage sehr viele kleine Einzeldateien sind.

Modulares Arbeiten mit Sass

Das Tool meiner Wahl ist Sass. Auch bei Sass werden einzelne Dateien in ein zentrales Stylesheet importiert. Doch Sass wird auf dem Entwicklungsrechner interpretiert. Am Ende wird eine einzelne CSS-Datei generiert, die dann wiederum im Projekt genutzt wird. Es besteht also niemals die Gefahr, dass durch eine Unachtsamkeit eine CSS-Datei mit weiteren 120 importierten CSS-Dateien live geht.

Die Arbeit mit Sass ermöglicht es mir, meine Arbeitsdateien systematisch zu ordnen. Jeder Modultypus – bspw. Teaser, Header, Karussell, Formular – bekommt ein eigenes Verzeichnis. Darin hat jedes Modul eine Datei, in der alle relevanten Auszeichnungen vorgenommen werden.

Sollten sich Gemeinsamkeiten zwischen Modulen entwickeln, können diese in Mixins oder Placeholder ausgelagert werden. Der somit abstrahierte Code kann dann noch einfacher zwischen Projekten ausgetauscht werden.

Mixins kann man sich wie einfache Funktionen in einer Programmiersprache vorstellen. Placeholder hingegen sind "stille Klassen". Sie werden im Prinzip wie Klassen geschrieben und haben keinerlei Konfigurationsinterface. Sie werden aber nicht wie Klassen selber in das CSS ausgegeben. Sie verbleiben immer innerhalb ihrer Sass-Datei.

- sass
  -> config
  -> mixins
  -> modules
  -> Framework

  _config.scss
  _modules.scss

  oldie.scss
  styles.scss

Der Aufbau eines typischen Sass-Projektes sieht bei mir recht einfach gestrickt aus. Auf der obersten Ebene des Sass-Ordners befinden sich wenige Dateien und Ordner. Die Dateien oldie.scss und styles.scss werden am Ende kompiliert und als CSS-Dateien ausgegeben. Die Datei oldie.scss enthält alle Regeln für den IE8. Diese Datei sollte langsam obsolet werden. Doch gerade im "Enterprise"-Bereich und in der öffentlichen Verwaltung ist die IT noch gerne in der Antike und der IE8 ist der Arbeitsbrowser.

Der Ordner "mixins" beinhaltet Hilfsdateien für Sass, also die Mixins und Placeholder. Der Ordner "Framework" wird nach dem verwendeten Framework benannt, falls ich eines nutze. Nutze ich kein Framework, entfällt dieser Ordner logischerweise. Im Ordner "config" stecken alle Konfigurationsdateien. Üblicherweise sind dies etwa vier. Die eigentliche Arbeit geschieht im Ordner "modules". Dessen Inhalte auf erster Ebene werden in die Datei _modules.scss inkludiert, diese wird wiederum in die oldie.scss und styles.scss inkludiert.

Ich habe mir angewöhnt, immer dann einen Ordner zu erstellen, wenn es zu einem Themenbereich mehr als eine Datei gibt. Deshalb stecken im Ordner "modules" wieder zahlreiche Ordner, deren Inhalte auf der oberen Ebene in einer Überblicksdatei verlinkt/importiert werden.

Dieser stringente Aufbau gibt mir eine Ordnung an die Hand, die einen genaueren Blick in Debugger-Tools obsolet macht. Schließlich muss ich nur im Ordner sass\modules\footer\ die Datei _copyrighthint.scss anschauen, um den Copyrighthinweis im Footer zu formatieren. Oft befinden sich in den Moduldateien nur wenige Zeilen CSS.

Am Namen sollst Du sie erkennen

Eine Namenskonvention ist, auch wenn man nicht im Team arbeitet, eine gute Idee. Schließlich möchte man selbst auch in ein paar Monaten den eigenen Code leicht verstehen können. Oder ein Kollege übernimmt das Projekt und soll sich möglichst schnell zurechtfinden können.

Es gibt zwei Aspekte einer Namenskonvention:

  1. Namen sollten möglichst abstrakt gehalten sein.
  2. Namen sollten immer gleich aufgebaut sein und die Selektion sowie die Abschottung zu anderen Modulen erleichtern.

Abstrakte Namen

In vielen Webseiten begegnen uns Klassen, die eine Optik implizieren, wie bspw. .red. Ist man bereit, den Klassennamen auszutauschen, wenn in der Entwurfsphase oder nach dem Livegang die Optik des betreffenden Elements nicht mehr rot, sondern orange ist, dann kann man gerne solche Klassen nutzen. Oft werden optische Veränderungen aber nicht durch den Tausch von Klassen in Templates, sondern durch die Bearbeitung des CSS realisiert. In einem solchen Falle ist eine Klasse .red, die in Wahrheit ein Orange transportiert, keine gute Idee.

Gerne wird in diesem Zusammenhang auch von "semantischen Klassen" gesprochen. Ich halte dies für den falschen Begriff. Für die Semantik einer Webseite ist HTML zuständig. Ob und wie wir die Klassenattribute benutzen, hängt nur von unseren Designs ab. Sie transportieren weder für den Browser noch für den Endnutzer eine Bedeutung. Klassen sind Vehikel, um der Webseite ein Design zu geben. Die Klassennamen müssen für die Entwickler praktikabel und verständlich sein. Aber sie müssen keine Bedeutung transportieren.

Gleicher Aufbau der Namen

Für alle Beteiligten sollte klar sein, ob Klassen auf Englisch, Deutsch oder einer anderen Sprache formuliert werden sollen. Das ist eine recht banale Ebene, auf der schnell Einigkeit erreicht werden kann. Schwieriger ist es, genaue Benamungsrichtlinien im Team festzulegen und sich auch daran zu halten.

Mittlerweile haben sich die Namenskonventionen von SMACSS [3] und BEM [4] als die Gebräuchlichsten durchgesetzt. BEM setzt den Fokus komplett auf das Modul – hier "Block" genannt. SMACSS hingegen weist Module und andere CSS-Regeln einer von fünf Kategorien zu:

  1. Base – Reset-CSS oder Normalisierung [Prefix: b-]
  2. Layout – meist ein Grid [Prefix: l-]
  3. Module – die eigentlichen Inhaltselemente [kein Prefix]
  4. State – bspw. ein Akkordeon, das auf- oder zugeklappt ist [Prefix bspw. is- oder has-]
  5. Theme – ohne das HTML anzufassen wird ein Auftritt neu "lackiert" [Prefix: theme-]

Ein Teaser kann mit beiden Methodiken folgendermaßen ausgezeichnet werden:

<!-- SMACSS -->
<div class="teaser">
  <header>
    <h3>Überschrift</h3>
  </header>
  <div class="teaser-content">

  </div>
  <footer>
    <a href="#">weiterlesen</a>
  </footer>
</div>

Bei SMACSS erfolgt ein sparsamer Einsatz von Klassen. Es wird empfohlen, da wo es sinnvoll und machbar ist, Elementselektoren im CSS zu nutzen. In diesem Beispiel wäre deshalb zu klären, ob es nicht sinnvoller wäre, die Überschrift oder den sie umgebenden Container mit einer Klassen zu versehen. Dann könnte bei der Implementierung eine andere Überschriftenhierarchie genutzt werden, ohne dass es optische Auswirkungen hätte.

Bei BEM hingegen bekommt jedes Element eine Klasse. Die Verwendung von Elementselektoren ist verpönt.

<!-- BEM -->
<div class="teaser">
  <header class="teaser__headline-container">
    <h3 class="teaser__headline">Überschrift</h3>
  </header>
  <div class="teaser__content">

  </div>
  <footer class="teaser__footer">
    <a href="#" class="teaser__footer-link">weiterlesen</a>
  </footer>
</div>

Es wird immer wieder diskutiert, wie lang die Namensketten gehen dürfen. Ich rate davon ab, neben .modul und .modul__kind-element auch .modul__kind-element__enkel-element zu schreiben. Stattdessen ist .modul__enkel-element handlicher und sicherlich genauso verständlich.

Sie sollten sich mit beiden Ansätzen ein wenig beschäftigen, damit Ihnen klar wird, welcher Ansatz Ihnen besser gefällt. Schließlich müssen Sie mindestens ein Projekt damit durchstehen, bis Sie ein anderes System ausprobieren können.

Bedenken Sie dabei immer, dass Sie das alles nur deshalb tun, damit Sie besser im Team arbeiten können und für nachfolgende Entwickler die Arbeit einfacher wird, weil die Namenskonvention eine gewisse Logik mit sich bringt. Den Browsern und den Nutzern Ihrer Webseite ist es egal, wie die Klassen heißen und wie sie geschrieben sind.

So sollte CSS nicht geschrieben werden

/* von Bootstrap */

.table > thead > tr > th,
.table > thead > tr > td,
.table > tbody > tr > th,
.table > tbody > tr > td,
.table > tfoot > tr > th,
.table > tfoot > tr > td {
  vertical-align: top;
}

/*  besser */

.table th, .table td {vertical-align: top;}

Das Bootstrap-Beispiel ist zu komplex. Alle nur erdenklichen Arten von td und th werden gelistet. Also kann man schlicht verkürzen. Verkürzung ist auch hier angesagt:

nav.navigation > ul > li > .submenu > ul > li.archive:hover {
    border: 2px solid transparent;
}

CSS-Regeln werden immer von rechts nach links gelesen. Das macht der Browser und das machen auch Sie, wenn Sie jemandem diese Regel erklären wollen: "Jedes List-Element mit der Klasse .archive über das mit einer Maus gefahren wird und das direktes Kindelement einer ungeordeneten Liste ist, die wiederum direktes Kindelement eines Elementes mit der Klasse .submenu ist, das direktes Kindelement eines Listenelementes ist, das direktes Kindelement einer ungeordeneten Liste ist, das direktes Kindelement eines nav-Elementes mit der Klasse navigation ist."

Sie sehen: Diese Regel ist extrem kompliziert. Sie ist, ohne den Code genauer zu kennen, mit Sicherheit unnötig kompliziert. Schreiben Sie CSS defensiv. Schreiben Sie nur soviel wie nötig. Erst wenn die Regeln nicht ziehen, fügen Sie eine weitere Ebene hinzu, um die Spezifität [5] zu erhöhen. Wir können die Regel auch folgendermaßen formulieren:

/* kürzer */

.navigation .archive:hover {
    border: 2px solid transparent;
}

Würden wir BEM nutzen (oder uns davon inspirieren lassen), könnten wir die Regel auch so schreiben:

/* kürzer */

.navigation__archive:hover {
    border: 2px solid transparent;
}

Modulares Arbeiten in der Entwurfsphase

Frontendentwicklung ist eine komplexe Materie. Denn obwohl die verwendeten Sprachen rein formal betrachtet nicht besonders schwer zu erlernen und auch nicht komplex sind, ist die professionelle Praxis sehr wohl komplex. Denn die Ziele unserer Arbeit – unbekannte Browser in unbekannten Kontexten von unbekannten Nutzern – machen Frontendentwicklung so kompliziert.

Die Wahrheit liegt im Browser, nicht in Photoshop.

Und da wir schon seit einiger Zeit nicht mehr nur für eingrenzbare Desktoprechner entwickeln, sondern ein immer komplexer und variantenreicheres Feld bestellen müssen, ist das gewohnte Photoshop-Layout noch weniger aussagekräftig, als es schon immer war. Wenn wir gute Arbeit abliefern wollen, müssen wir uns schnell von der Bildvorlage aus Photoshop (oder Fireworks oder ...) lösen und die Designideen in Code umsetzen. Die Ausgestaltung und Endfertigung des Layouts sollte in Code passieren. Die Wahrheit liegt im Browser, nicht in Photoshop.

Um in dieser Entwurfsphase flexibel mit den Inhaltselementen umgehen zu können und den fraglichen Code schnell zu finden, ist modulare Webentwicklung eine sehr große Hilfe. Setzen Sie möglichst schnell erste Layouts in Code um und erstellen Sie einen Klickdummy. Dieser ist dann die wichtige Referenz, um die Tauglichkeit des Layouts zu überprüfen.

Auch Designer können modular arbeiten, nicht nur Entwickler. Das erleichtert die Kommunikation, könnte allerdings für viele Kunden mehr als gewöhnungsbedürftig sein. Im Konzept der Style-Tiles [6] ist angelegt, dass sich die Designer nicht mehr primär auf komplette Seiten konzentrieren und auch nicht mehr in kompletten Seitenlayouts kommunizieren. Der Fokus steht eindeutig auf den einzelnen Modulen, die dann auch in kleinere (oder größere) Übersichten zusammengefasst werden können. Hin und wieder sollten auch ganze Seitenlayouts aus diesen Modulen konstruiert werden, damit die Kommunikation mit dem Kunden erleichtert wird. Außerdem hilft der Gesamteindruck dabei, abzuschätzen, ob man auf dem richtigen Weg ist.

Anstatt ein komplettes Seitenlayout zu duplizieren und ein Modul zu ändern oder zu ergänzen, würde sich der Designer nur auf dieses Modul konzentrieren. Schließlich setzt der Frontendentwickler nachher auch nur dieses separate Modul um, nicht die ganze Seite. Modulare Webentwicklung hilft also allen Beteiligten, sich auf das in jeder Situation zur Diskussion stehende Detail zu konzentrieren.

Fazit

Das Frontend sollte aus purem Eigennutz modular entwickelt werden. Schließlich bestehen Webseiten nur aus lose zusammengekoppelten Modulen. Neue Webseiten entstehen viel schneller, wenn alle Einzelteile problemlos zusammenpassen und beliebig kombiniert werden können. Es erfordert ein wenig Disziplin bei der Benamung von Modulen und beim Schreiben von CSS. Doch diese Disziplin zahlt sich später aus. Ziel eines jeden Frontendentwicklers sollte es sein, sein eigenes Bootstrap zu erstellen, das mit der Zeit wächst.

Autor

Jens Grochtdreis

Jens Grochtdreis ist freier Webentwickler und Berater. Er ist auf moderne Frontendentwicklung und Barrierefreiheit spezialisiert.
>> Weiterlesen
botMessage_toctoc_comments_9210