CSS ist keine Programmiersprache. Mittels CSS soll die Optik einer Webseite beeinflusst werden. Dabei geht es um Layout und Design.

Anhand eines Layouts organisieren wir Inhalte auf einer Seite. Es geht hierbei um das horizontale und vertikale Arrangement der Inhalte. Von Design sprechen wir hingegen, wenn wir die Optik der Inhalte verändern — und sie im Idealfall hübsch machen.

Da CSS nun keine Programmiersprache ist, gibt es auch keine Notwendigkeit, Eigenarten von Programmiersprachen mitzuführen. Es sind hingegen ganz eigene Funktionsweisen notwendig. Es gibt davon drei: die Kaskade, die Spezifität und die Vererbung. In dieser Einführung in die CSS-Grundlagen schauen wir sie uns nacheinander an.

Die Kaskade

Das C in CSS steht für “Cascading”. Die Kurzversion könnte lauten: “Wer zuletzt kommt, malt zuerst!” Definieren Sie also ein Element, eine Klasse oder eine ID mehrfach in einem Stylesheet, so überschreiben sich die Werte gleicher Eigenschaften. Die im Code nachfolgende Eigenschaft überschreibt die zuvor notierte. Das ist ganz einfach zu erklären: jegliche Datei wird von oben nach unten gelesen und verarbeitet. Folgen gleichartige Regeln nacheinander, überschreibt die zuletzt in der Datei befindliche die davor:

/* irgendwo in einer CSS-Datei */
p {
color: red;
border: 1px dotted #ddd;
padding: 8px;
}

/* irgendwann danach in der gleichen Datei */
p {
color: black;
}

Wichtig ist dabei, dass nur gleiche Eigenschaften überschrieben werden. Im obigen Beispiel würde also nur die Schriftfarbe geändert werden, der Rahmen und der Innenabstand blieben unangetastet.

Die Kaskade gilt übrigens auch dateiübergreifend. Wenn mehrere CSS-Dateien abgerufen werden, so gilt auch hier die Reihenfolge. Die erste Regel im obigen Beispiel könnte in der Datei allgemein.css stehen, während die zweite in theme-12.css stehen könnte, wobei Letztere auch als letztes geladen werden würde. Auch in diesem Fall wirkt die Kaskade.

Die Spezifität

Ein wenig Verwirrung kann stiften, dass die Kaskade nur so lange gilt, bis die Spezifität ins Spiel kommt. Bei der Spezifität geht es darum, ob eine Regel im wahrsten Sinne des Wortes spezifischer ist, als eine andere:

a {
color: red;
}

/* Jetzt wird es spezifischer */
p a {
color: blue;
}

In diesem Beispiel werden alle Links generell mit der Schriftfarbe rot versehen. An einer anderen Stelle werden alle Links, die sich in einem Absatz befinden, mit der Farbe blau versehen. Alle Links, die sich bspw. in Listen befinden, sind weiterhin rot. In diesem Falle ist sogar die Reihenfolge im Code, also die Basis der Kaskade, irrelevant. Denn die höhere Spezifität der zweiten Regel hebt die allgemeine Regel auf.

So einfach und schnell ist die Spezifität aber nicht abgearbeitet. Während sich die Kaskade schlicht auf die Reihenfolge im Code bezieht, ist der Bezugspunkt für die Spezifität der Selektor selber. Je nach Art und Komplexität des Selektors muss es also Unterschiede geben. Diese werden üblicherweise in Zahlen ausgedrückt. Denkt man sich in den folgenden Codebeispielen die Kommata weg, entstehen Zahlen. So sind die Gewichtungsunterschiede einfacher zu erfassen:

/* Spezifität 0,0,1 (ein Element) */
a { }

/* Spezifität 0,0,2 (zwei Elemente) */
p a {}

/* Spezifität 0,0,2 (zwei Elemente) */
/* Der Kindselektor selber hat keine Spezifität. */
p > a {}

/* Spezifität 0,1,0 (eine Klasse) */
.my-class {}

/* Spezifität 0,1,0 (ein Attributselektor) */
[class=”my-class”] {}

/* Spezifität 0,1,1 (eine Klasse und ein Element) */
a.my-class {}

/* Spezifität 0,1,2 (eine Klasse und zwei Elemente) */
p a.my-class {}

/* Spezifität 1,0,1 (eine ID und ein Element) */
a#my-id {}

  • Elemente und die Pseudo-Elemente :before und :after haben eine Wertigkeit von “0,0,1”.
  • Klassen, Attribut-Selektoren und Pseudo-Selektoren (bspw. :first-child) haben eine Wertigkeit von “0,1,0”.
  • IDs haben eine Wertigkeit von “1,0,0” und überschreiben damit alles in einem externen Stylesheet.
  • Einzig Inline-Styles überschreiben wiederum alles andere, weil sie generell eine Wertigkeit von “1,0,0,0” haben.

Inline-Styles können demnach von externen Stylesheets nur mittels des Schlüsselwortes !important überschrieben werden. Doch gehen Sie mit diesem Schlüsselwort sehr vorsichtig um. Es behindert Sie meist mehr, als dass es Ihnen hilft. Für das Schreiben einer Utilityklasse, die beispielsweise immer für fett-formatierten, roten Text sorgen soll, ist !important sehr geeignet. Aber nicht für normale Designentscheidungen. Je häufiger !important in Ihrem CSS vorkommt, umso eher haben Sie einen Konzeptionsfehler in Ihrem Code gemacht.  

Spielen Sie doch ein wenig mit diesem Spezifitäten-Rechner herum. Sie werden möglicherweise Aha-Erlebnisse über Problemfelder Ihres Codes erleben:

See the Pen
Specificity Calculator
by Jens Grochtdreis (@jensgro)
on CodePen.

Die Vererbung

Parallel zu den beiden eben erläuterten wichtigen Prinzipien gibt es die Vererbung. Die Werte einiger ausgesuchter Eigenschaften vererben sich im DOM-Baum auf das jeweilige Kindelement, bis sie neu definiert werden. Wir kennen das von Schriftart, -farbe und -größe. Normalerweise werden alle drei Eigenschaften auf dem body-Element definiert und gelten sodann prinzipiell für die gesamte Seite. Jedenfalls solange, bis sie neu definiert werden. 

Es ist logisch nachvollziehbar, dass Schriftart und -farbe sich gerne vererben dürfen und dadurch Codezeilen sparen, margin, padding oder border sich aber am besten nicht vererben sollten. Ansonsten würde es entweder ein optisches Chaos geben oder das CSS würde vor Reset-Regeln nur so strotzen.

Anders denken

Für viele Softwareentwickler scheinen diese Konzepte sehr fremd zu sein und eine gewisse Abwehrhaltung hervorzurufen. Nicht umsonst gibt es immer wieder Diskussionen auf Twitter und in Blogs, dass CSS “kaputt” sei. Das stimmt nicht. CSS ist nur nicht wie JavaScript, PHP oder Java. Aber es reicht doch schon, dass Java so ist wie Java. 

CSS ist keine Programmiersprache, und die Bestimmung als Designsprache hat die drei eben besprochenen Prinzipien geprägt. Sie sind aus dieser Sicht logisch und notwendig. Sie ermöglichen es uns, mit wenig Code einen großen Effekt zu erzielen. Denn nur mit der Gestaltung der in einer Seite verwendeten Elemente können wir schon ein Design erringen. Werden wir spezifischer, indem wir Klassen benutzen, können wir Unterscheidungen einführen und das Design ausdifferenzieren. Je mehr Klassen wir benutzen, umso ausdifferenzierter wird unser Design. 

Klassen sind so etwas wie if-Schleifen in der Programmierung. Nur wenn die Bedingung der Existenz einer Klasse existiert, gilt die Regel:

/* CSS */
.my-class {color: red}
.my-class-2 {color: blue;}

/* JavaScript */
var myClass = document.querySelector(".my-class");

if (myClass) {
myClass.style.color = "red";
}

Kaskade, Spezifität und Vererbung helfen dabei, die globale Natur von CSS zu realisieren. Das ist weder ein Bug, noch zu kritisieren. Es ist eine schlichte Notwendigkeit, mit der man umgehen muss. Denn schließlich wurde CSS zum Design von Webseiten geschaffen. Das funktioniert dann besonders gut, wenn man nicht jedes kleine Einzelteil separat gestalten muss, sondern global Absätze oder Listen-Elemente gestalten kann.

Doch genauer betrachtet wirken CSS-Regeln ja nicht generell global. Durch die verschiedenen Selektoren, Klassen und IDs können Web-Entwickler die Wirkung sehr spezifisch steuern (Spezifität!). Das Unbehagen vieler CSS-Kritiker scheint also darin begründet zu sein, dass sie die wahre Natur von CSS noch nicht vollständig durchdrungen haben. 

Mit den oben diskutierten Techniken können Sie wunderbar effizient arbeiten. Hier ein paar Tipps:

  1. Definieren Sie alle Formular-Elemente gerne global über Elemente und Attribut-Selektoren. Denn Formular-Elemente sehen normalerweise auf einer Seite identisch aus. Abweichungen können mit Klassen gestaltet werden.
  2. Gestalten Sie alle gängigen Elemente, die Redakteure über einen WYSIWYG-Editor einfügen würden. Diese Elemente werden keine separaten Klassen bekommen und sind so als allgemein gestaltete Elemente am besten.
  3. Geben Sie jedem Modul einer Seite eine eigene Klasse und benennen Sie deren Elemente in Abhängigkeit zu dieser Modul-Klasse. Diese Methode nennt man BEM. Sie ist die mittlerweile wohl gängigste Methode zur Auszeichnung von Klassen. 
  4. Nutzen Sie möglichst keine ID im CSS, weil Sie dann nur ein Element pro Seite nutzen können. Damit holen Sie sich eine unnötige Beschränkung ins Projekt.
  5. Vermeiden Sie lange Selektoren-Ketten und das Schlüsselwort !important so gut es geht.
  6. Beginnen Sie jede Regel mit der Klasse des Moduls. Vermeiden Sie Selektoren, die eine Struktur vordefinieren. 

Einführung in die CSS-Grundlagen – Fazit

Mit diesen wenigen Regeln kommen Sie ohne Probleme durch Ihre Projekte. Bedenken Sie bitte immer, dass es sich bei CSS um keine Programmiersprache handelt und sie deshalb auch nicht wie eine behandelt werden darf. Wer sich auf die eigene Gedankenwelt von CSS einlässt, wird ihre Einfachheit und Eleganz zu schätzen lernen.

Photo by Lee Campbell on Unsplash
Jens Grochtdreis

Große Auswahl an günstigen Domain-Endungen – schon ab 0,08 € /Monat
Jetzt Domain-Check starten