Teil 3:
Wie BEM unsere Art CSS zu schreiben veränderte
Im dritten Teil unserer Artikelserie CSS-Kurs für Contao wollen wir euch BEM vorstellen, eine Namenskonvention für CSS-Klassen. BEM hat unsere Art CSS zu schreiben von Grund auf verändert. Vielleicht verändert es auch Eure.
In den letzten beiden Artikeln haben wir an der ein oder anderen Stelle schon durchblicken lassen, dass wir seit ein paar Projekten auf BEM setzen. Inhaltlich betrachtet, hätten wir BEM durchaus auch schon im ersten Artikel CSS-Klassen benennen, aber auch im zweiten Teil CSS einfach halten unterbringen können.
Nachdem wir aber zuletzt einen Hinweis bekamen, dass wir mit jeweils über 2.000 Wörtern hart an der Grenze der zumutbaren Artikellänge liegen, sind wir eigentlich ganz froh, dass wir uns dazu entschieden haben, BEM einen eigenen Artikel zu widmen.
Was ist BEM?
BEM steht für BLOCK, ELEMENT, MODIFIER und ist eine von der russischen Suchmaschine Yandex entwickelte Namenskonvention (zur Website). Wir nutzen BEM in erster Linie, um unsere CSS Klassen transparent und für andere Entwickler nachvollziehbar zu halten. Die Regeln für die Klassen-Benennung sind zwar etwas strikter, aber wenn man sie erstmal verinnerlicht hat, gehen auch sie relativ leicht von der Hand.
Die BEM-Syntax
BEM stellt es euch grundsätzlich frei, welche Art von Trenner ihr zwischen block
und element
oder modifier
verwenden wollt. Wenn ihr aber andere Artikel zum Thema BEM lest, werdet ihr, gerade bei neueren Artikeln, häufig unsere Schreibweise mit doppeltem Unterstrich bzw. doppeltem Bindestrich wiederfinden:
.block {}
.block__element {}
.block--modifier {}
Als .block
bezeichnen wir die übergeordnete Komponente, .block__element
ist ein Kindelement von .block
und .block--modifier
ist eine Variante oder Version von .block
.
Ein Beispiel: BEM-Klassen im Einsatz
Um die Zusammenhänge zwischen Block, Element und Modifier ein wenig zu verdeutlichen, ein Beispiel: Wir wollen die Navigation einer Website gestalten.
<nav class="mod_navigation block">
<ul class="level_1" role="menubar">
<li class="first"><a>Home</a></li>
<li><a>Über uns</a></li>
<li class="last"><a>Kontakt</a></li>
</ul>
</nav>
Nun wollen wir die BEM-Klassen-Bezeichnungen den einzelnen Teilen unserer Navigation zuordnen:
- Block: Unsere Navigation ist eine unabhängige Komponente, wir geben ihr deshalb die Klasse
.nav
. - Element: unsere ungeordnete Liste liegt innerhalb von
.nav
und bekommt, um die Zugehörigkeit zur Komponente zu verdeutlichen, die Klasse.nav__list
. - Modifier: da es sich bei unserer Navigation um eine Hauptnavigation mit kleinen grafischen Abweichungen handelt, geben wir ihr zusätzlich die Klasse
.nav--main
.
<nav class="mod_navigation nav nav--main block">
<ul class="level_1 nav__list" role="menubar">
<li class="first"><a>Home</a></li>
<li><a>Über uns</a></li>
<li class="last"><a>Kontakt</a></li>
</ul>
</nav>
Der Vorteil: Durch den gemeinsamen Stamm .nav
lassen sich so relativ leicht alle zusammengehörigen Klassen erkennen und das sowohl in unserer CSS als auch in unserem HTML-Code.
Der Nachteil: Durch die Wiederholung des Stamms werden die Klassenbezeichnungen länger. Damit dies nicht in ellenlangen Klassennamen ausartet, lautet eine wichtige Regel, dass die Klassenbezeichnung nicht die HTML-Baumstruktur widerspiegeln soll.
Statt also das Listenelement als Kind der Liste zu deklarieren, benennen wir es lediglich als (weiteres) Kind der Navigation. Das Gleiche gilt für unseren Anker.
falsch:
.nav {}
.nav__list {}
.nav__list__item {}
.nav__list__item__link {}
richtig:
.nav {}
.nav__list {}
.nav__item {}
.nav__link {}
So bleiben die Klassennamen einigermaßen kurz, trotzdem ist der Zusammenhang zwischen Blöcken und Elementen sofort erkennbar.
Aber BEM ist hässlich
Tatsächlich hat es auch bei uns eine Weile gedauert, bis wir uns mit der ungewohnten Schreibweise von CSS-Selektoren anfreunden konnten. Ja, BEM ist hässlich. Aber ist das ein Grund, es nicht zu nutzen?
Und wenn wir mal ehrlich sind, spielt doch die Ästhetik von CSS-Klassennamen eher einer untergeordnete Rolle, oder? Der Vorteil, der sich allerdings daraus ergibt, Blöcke, Elemente und ihre Modifikationen auf einen Blick unterscheiden zu können, ist nicht zu unterschätzen.
Hinzu kommt, dass sich die BEM-Syntax in einer Contao-Website auf den ersten Blick erkennen lässt. Durch die doppelten Unterstriche und Bindestriche werdet ihr eure eigenen Klassen und die Contao-Klassen immer auseinander halten können.
Warum eigentlich BEM?
Als das Thema modulares CSS für uns aktuell wurde, hatten wir die Qual der Wahl: von SMACSS und OOCSS hatten wir schon ein bisschen was gehört und mit ACSS preschte eine weitere CSS-Namenskonvention nach vorne.
Wir haben uns letztendlich für BEM entschieden, weil es uns im Gegensatz zu beispielsweise SMACSS die wenigsten Vorgaben in anderen Bereichen machte. Wir wollten uns (noch) nicht festlegen, wie wir unsere SCSS-Dateien zu organisieren und zu benennen haben. Und die bereits erwähnte, eindeutige Schreibweise mit doppelten Binde- und Unterstrichen sorgte gerade in Contao dafür, dass wir unsere Stylings sofort wiedererkannten.
Wie und wann nutzen wir BEM?
Vor etwa 9 Monaten haben wir damit begonnen, BEM langsam in unseren Workflow zu integrieren. Anfangs nur vereinzelt, bei einfachen Komponenten und Modifikationen, nutzen wir die BEM-Syntax mittlerweile bei allen neuen Projekten und über die gesamte Website hinweg.
Trotzdem würde ich nicht behaupten, dass wir – wie sagt man so schön – es „drauf hätten“. Sicherlich, bei immer wiederkehrenden Modulen wie Navigationen oder Headerbildern muss man nach dem 4. Projekt nicht mehr lange grübeln. Aber es gibt immer wieder Situationen, in denen wir uns nicht ganz sicher sind, welche Zuordnung nun wirklich sinnvoll ist, also was ein Element eines Blocks ist und was vielleicht ein ganz eigener Block sein könnte.
Auch gibt es Teile einer Website, bei denen es zumindest vorerst keinen Sinn ergibt, BEM zu verwenden, zum Beispiel bei unserem Website-Logo. Natürlich könnten wir auch hier die BEM-Schreibweise anwenden:
.logo {}
.logo__link {}
.logo__img {}
Aber wozu?
Auch wenn ich das Logo später um eine Variante .logo--dark
erweitere, heißt das nicht zwangsläufig, dass ich alle Kindelemente nun mit den entsprechenden BEM-artigen Klassennamen versehen muss. Hier ist es wichtig jeden Fall für sich zu betrachten und dann zu entscheiden, ob BEM sinnvoll ist oder nicht.
Wenn ihr dadurch allerdings an die empfohlene Grenze von 3 Ebenen bei der Verschachtelung von Klassen kommt, dann solltet ihr auf jeden Fall mal drüber nachdenken, um euren CSS Specifity Score niedrig zu halten (siehe auch Teil 2).
Umgekehrt kann es euch genauso gut passieren, dass ihr CSS-Anweisungen für ein Element, zum Beispiel für eine Headline, zunächst nur innerhalb eines Blocks verwendet und im Laufe der Zeit feststellt, dass ihr die Gestaltung auch an anderen Stellen einsetzen möchtet:
<div class="block-list">
<h2 class="block-list__headline"></h2>
</div>
In diesem Fall empfehlen wir euch, im Sinne der besseren Wiederverwendbarkeit, den Klassennamen aus der BEM-Struktur zu lösen und eine eher allgemeine Klassenbezeichnung wie .hl-large
zu verwenden. Dadurch, dass der Wortstamm block-list
fehlt, wird auch gleich deutlich, dass keine Gestaltungsanweisungen für Headline im Bereich block-list
zu erwarten sind.
BEM in Contao einsetzen
Wenn es darum geht, BEM in Contao zu verwenden, bin ich immer wieder hin- und hergerissen. Am Liebsten würde ich große Teile meines Codes nach der BEM-Syntax strukturieren. Gleichzeitig möchte ich aber in Contao möglichst wenige Templates anpassen, um mir nicht bei späteren Updates und größeren Änderungen am Contao-Core Steine in den Weg zu legen (siehe auch Teil 1: Die Praxis).
Deswegen fahren wir momentan noch ein wenig zweigleisig und setzen BEM noch nicht so konsequent ein, wie wir es manchmal gerne würden. Aber Hoffnung ist in Sicht: Seit längerer Zeit ist die Rede von einen Contao-Call zum Thema CSS-Standards. Noch steht allerdings kein Termin fest.
Contao hat durch die einfache Einbindung von externen Stylesheets und sogar der Verarbeitung von SCSS und LESS-Dateien bereits eine Menge getan, um Entwicklern den Umgang mit CSS einfacher zu machen. Jetzt wäre es an der Zeit, auch die noch aus Typolight-Zeiten stammenden Klassenbezeichnungen zu überdenken. Wir werden auf jeden Fall versuchen, bei diesem Call dabei zu sein.
Fragen?
Habt ihr noch Fragen zu BEM oder CSS-Klassenbenennung im Allgemeinen? Nutzt ihr vielleicht sogar BEM oder einen der anderen Ansätze zum Schreiben von modularem CSS? Lasst es uns wissen, per Mail oder in den Kommentaren.
Kommentare
Kommentar von zonky |
Dank für die tolle Artikelserie!
Antwort von Dennis Erdmann
Moin zonky,
freut mich, dass sie Dir gefällt und motiviert uns, weiterzumachen.
Kommentar von Kevin |
Vielen Dank für den super Beitrag. Habe heute das erste Mal von BEM gehört und finde es sehr Interessant für unsere Projekte. Schön das ihr euch Zeit genommen habt euer Wissen zu teilen.
Kommentar von Sigi |
Also eine Sache muss ich schon anmerken:
"Aber BEM ist hässlich"
Ja das ist fuer mich tatsaechlich relevant. Ästhetik ist eine Sache die in einem waechst. Das ist eine Sache die gefuehlt auch nicht von irgendwo herkommt sondern auch ein Zeichen von Anspruch und Qualitaet ist.
Hochwertige Produkte/Dinge sehen selten unaesthetisch aus.
Das ist als wuerd ich mir ein Sandwich machen und die verschimmelte Tomate darunter legen weil ich sie sowieso nicht sehe.
Unabhaengig davon hab ich persoenlich jetzt keine Praeferenz. Gegen oder fuer BEM, gefuehlt seh ich den grossen Vorteil einfach nicht.
Antwort von Dennis Erdmann
Moin Sigi,
ich glaube, dass man sich mit Ästhetik im Code bzw. CSS keinen Gefallen tut. BEM ist ein Standard, der es einfacher machen soll, Klassennamen zu finden und zu verwenden.
Ich würde BEM auch nicht mit einer verschimmelten Tomate vergleichen, aber um bei deinem Bild zu bleiben: BEM ist die Art wie du eine Tomate schneidest, damit sie perfekt auf deinem Sandwich verteilt ist. Da du sie sowieso nicht siehst, ist es nicht so schlimm, dass sie Stücke in eine etwas ungewöhnliche Form geschnitten wurden.
Was „den großen Vorteil“ betrifft: Jeder hat da seine eigenen Vorlieben. Nur wenn man im Team an Projekten arbeitet, sollte man sich auf einen gemeinsamen Standard einigen. Ob das nun BEM oder eine andere Schreibweise ist, ist gar nicht so wichtig.
Kommentar von neophron |
@ Sigi
Zitat: »Hochwertige Produkte/Dinge sehen selten unaesthetisch aus.«
Es gibt so viele Beispiele, wo die Verpackung ästhetisch aussieht und der Inhalt Sondermüll ist.
Wenn ich die Möglichkeit habe, durch eine Logik im css Aufbau Zeit zu sparen und anderen Entwicklern, die später an dieser css-Datei etwas ändern müssen, die Arbeit zu erleichtern, ist das für mich hochwertig.
Kommentar von Micha Pietsch |
Hallo Dennis,
CSS-Standards beschäftigen mich schon lange. Die ultimativ perfekte Lösung hab ich noch nicht gefunden. Auch ich möchte möglichst wenige Templates anpassen und als zweiten Schwerpunkt Regression-Fehler begrenzen.
Modularität sollte genau das umsetzen: Wirkungsbereiche klar definieren. Wie ist eure Erfahrung mit Regression / unerwünschten Nebenwirkungen bei Änderungen? Wie entwickelt sich mit BEM (oder mittlerweile anderen Methoden) euer Refactoring-Aufwand im Lauf eines Projektes oder bei neuen Änderungen nach längeren Pausen?
Viele Grüße,
Micha
Antwort von Dennis Erdmann
Moin Micha,
ich weiß nicht, wie es anderen geht, aber BEM hat wie alle Systeme seine Stärken und Schwächen. Auch wenn sich mit BEM ein paar Fehler vermeiden lassen, so kommt es doch immer wieder vor, dass Bezeichnungen während eines Projektes angepasst werden sollten. Das finde ich auch nicht weiter schlimm, der Aufwand hält sich dennoch in Grenzen.
Nach Fertigstellung mache ich solche Änderungen allerdings nur noch sehr selten. Dann lebe ich lieber mit meinen „Bezeichnungsfehlern“ und mache es bei der nächsten Version / dem Relaunch besser.
Kommentar von Micha Pietsch |
Moin Dennis :)
kann ich total nachvollziehen, was Bezeichnungen vergeben betrifft.
Mir ist wichtig, bei langfristig zu pflegenden Projekten die Geschwindigkeit halten können als Dev-Team, auch wenn der Code natürlich größer und komplexer wird. Das meinte ich vor allem: Wenn man an einer Stelle ändert und hoffentlich nirgends anders etwas kaputt macht damit. :)
LG, Micha
Kommentar von Christian |
Hallo Dennis,
vielen Dank für den Artikel. Ich finde BEM überhaupt nicht hässlich, sondern mag diese strukturierte Ästhetik sehr. Man kann es super mit SCSS umsetzen/verschachteln und weiß ganz genau, woran man ist.
Damit gehört nun die Suche "Welche CSS-Regel überschreibt meine wegen welcher Priorität, Genauigkeit und Position" endlich der Vergangenheit an.
Aber dass man quasi jedes Template in Contao umschreiben muss (auch, wenn man Bootstrap container, row, column verwenden möchte) ist schon sehr ärgerlich - insbesondere da man nicht weiß, wie die Templates dann beim nächsten Update geändert werden (s. auch schema.org/structured data).
Hast du Infos, wann Contao sich mal auf eine (ausgeklügeltere) CSS-Syntax einigt?
Viele Grüße
Christian
Antwort von Dennis Erdmann
Moin Christian,
ich denke nicht, dass Contao eine neue CSS-Syntax einführt, es sei denn, jemand liefert ein fertiges und schlüssiges Konzept.
Ich habe mich mittlerweile auch ganz gut an BEM gewöhnt und empfinde die Schreibweise auch nicht mehr also so hässlich. Aber der Artikel liegt ja auch schon ein wenig zurück. Vielleicht habe ich mich einfach dran gewöhnt ?