„Don´t repeat yourself!“

Diesen Leitsatz, sollte man sich von Anfang an für objektorientierte CSS-Programmierung auf die Fahne schreiben.

Denn auch bei der 743igsten Wiederholung von Miami Vice, wird die schauspielerische Leistung von Don Johnson nicht besser. Wiederholungen sind langweilig. Alles schon mal gesehen, alles schon mal da gewesen.


Bei einem CSS-Code führen sie außerdem noch zu einem unschönen Nebeneffekt. Der Code bläht sich auf und wird irgendwann einfach nur noch unübersichtlich und was noch viel schlimmer ist, er wird unleserlich.
Das sind keine guten Voraussetzungen für eine gemeinsame Arbeit am Code und macht es später hinzugekommenen Programmierern schier unmöglich in den Code einzusteigen.

Hier ein kleines Bespiel, wie man es nicht machen sollte:

Nehmen wir an, wir haben vier Sektionen auf unserer Seite, die alle Überschriften der 3. Kategorie beinhalten (h3). In jeder Sektion sollen diese Überschriften formatierbar sein. Nun gut, dann machen wir das.

#secone h3 { font-size: 1.2em; }
#sectwo h3 { font-size: 1.2em; }
#secthree h3 { font-size: 1.2em; }
#secfour h3 { font-size: 1.2em; }

OK, das können wir noch ein wenig zusammenfassen:

#secone h3, 
#sectwo h3, 
#secthree h3, 
#secfour h3 {
    font-size: 1.2em;
}

Das funktioniert auch, ist aber nicht mehr Stand der Dinge. Kämen jetzt noch weitere Sektionen hinzu (#secfive, #secsix, etc.), so würden wir diese noch als weitere Selektoren aufführen und deren Verkettung würde immer größer und undurchsichtiger werden.

Das ist das eine Problem an dieser Schreibweise. Das andere sind die verwendeten IDs. IDs haben in der Vererbungshierarchie von CSS einen sehr hohen Stellenwert und werden sehr hoch gewichtet. Das erschwert das Überschreiben von ID-Selektoren ungemein und man muss schon einen ziemlichen Spagat hinlegen, möchte man eine ID überschreiben.

Ein kleiner Exkurs:

Die Gewichtung bei der Vererbung (Kaskadierung) in CSS spielt eine wichtige Rolle dabei, welche Formatierung sich durchsetzt oder überschrieben wird. Zu aller erst geht es nach der Reihenfolge im Code.

h3 { color: red; }
h3 { color: blue; }

Diese Reihenfolge würde uns eine blaue Überschrift dritter Ordnung anzeigen. Was würden wir sehen, wenn wir folgendes schreiben?

#hdl h3 { color: red; }
h3 { color: blue; }

Richtig! Die Überschrift würde rot bleiben, da die Gewichtung des ersten Selektors durch die ID wesentlich höher ist.

Nun, wie lässt sich das berechnen? Es gibt eine relativ simple Pie-mal-Daumen-Regel dazu. Damit teilt man die Selektoren in folgende Gewichtung ein:

ID (#hdl) = 100 Punkte
Klasse (.hdl) = 10 Punkte
Selektor (h3) = 1 Punkt

Mit diesen Punktevorgaben kann man sehr schnell sehen, welche Deklaration sich durchsetzen wird. In den oben genannten Beispiel wäre die Verteilung wie folgt:

#hdl h3 { color: red; } = 100 Pkt. + 1 Pkt. = 101 Pkt.
h3 { color: blue; } =  1 Pkt. = 1 Pkt.
101 Pkt > 1Pkt = “color: red” wird nicht überschrieben.

Wer damit mal ein wenig rumspielen möchte, kann sich auf der Seite http://specificity.keegan.st/ ein wenig austoben. Mit diesem Calculator lassen sich die unterschiedlichsten Kombinationen von Selektoren zusammenbauen und Ihr könnt sehen, welcher sich durchsetzen wird.

Kommen wir nun aber zu unserem Beispiel vom Anfang zurück und nähern uns der optimierten Version unseres Codes.
Um die Kette der Selektoren nicht ins Unendliche ausufern zu lassen, schaffen wir den ganzen Wust ab und überlegen uns, wie wir die Überschriften flexibler deklarieren können.

#secone h3, #sectwo h3, #secthree h3, #secfour h3 {
font-size: 1.2em;
}

Wie wäre es zum Beispiel damit:

h1, .h1 { font-size: 1.8em; }
h2, .h2 { font-size: 1.7em; }
h3, .h3 { font-size: 1.6em; }
h4, .h4 { font-size: 1.5em; }
h5, .h5 { font-size: 1.4em; }
h6, .h6 { font-size: 1.3em; }

Wir fügen der normalen h1- bis h6-Deklaration einfach noch eine jeweilige Klasse mit gleichem Namen hinzu. Das gibt uns eine enorme Flexibilität im Einsatz von Überschriften. Auf diese Weise ist es uns möglich, einer h3 die Größe einer h2 zu geben, ohne dass wir dies extra deklarieren müssen. Hier ein kleines Beispiel mit unseren vier Sektionen:

<div class="secone">
    <h3 class="h2">Eine H3 Überschrift mit Größe einer H2</h3>
</div>
<div class="sectwo">
    <h3>Eine H3 Überschrift in normaler Größe</h3>
</div>
<div class="secthree">
    <h3 class="h5">Eine H3 Überschrift mit Größe einer H5</h3>
</div>
<div class="secfour">
    <h3 class="h1">Eine H3 Überschrift mit der Größe einer H1</h3>
</div>

Ihr seht, dass unser CSS-Code sehr viel flexibler geworden ist und nun vielseitiger eingesetzt werden kann. Gehen wir noch einen Schritt weiter und gehen einmal davon aus, dass alle Sektionen die Selbe Grundformatierung besitzen sollen. Dann ergänzen wir unseren Code um eine weitere Klasse die wie folgt aussehen könnte:

.secbase {
    float: left;
    margin: 1em;
    border: 1px solid #ccc;
    color: #151515;
}

Diese Klasse weisen wir jetzt noch den einzelnen Sektionen zu und wir haben eine Einheitlichkeit geschaffen, die im Code an nur einer Stelle geändert werden muss.

<div class="secbase secone">
    <h3 class="“h2“">Eine H3 Überschrift mit Größe einer H2</h3>
</div>
<div class="secbase sectwo">
    <h3>Eine H3 Überschrift in normaler Größe</h3>
</div>
<div class="secbase secthree">
    <h3 class="“h5“">Eine H3 Überschrift mit Größe einer H5</h3>
</div>
<div class="secbase secfour">
    <h3 class="“h1“">Eine H3 Überschrift mit der Größe einer H1</h3>
</div>

Was hat das Ganze nun mit objektorientierter Programmierung zu tun? Nun, der Grundgedanke der OOP ist es, immer wiederkehrende Aufgaben in Klassen zu bündeln, um sie wiederverwendbar zu machen. Und genau das haben wir eben getan. Zugegeben hinkt der Vergleich zur klassischen OOP in PHP oder JavaScript etwas, aber der dahinter stehende Gedanke ist der Selbe.