Endlich Clean CSS

Eigentlich bin ich viele Jahre gut mit meinen CSS Kenntnissen ausgekommen, aber jetzt habe ich festgestellt, dass man doch nie auslernt und es doch besser geht.

Das sind die Zutaten:

  • Namenskonvention
  • LESS
  • Modularisierung
  • Bundling

Namenskonvention

Bei CSS gibt es einfach zu viele Namenskonventionen: die aus der .NET Ecke schwören auf “Camel-Casing” und die aus der PHP Ecke benutzen ganz unbewusst “Lower-Case-Underscore”. Mich hat die Konvention von Bootstrap überzeugt (denn das sind wirkliche Industry-Leader!) und dort wird die XML-Konvention benutzt.

Falsch:

  • .IntroText
  • .introText
  • .intro_text

Richtig:

  • .intro-text

Eine willkürliche Festlegung zwar, aber hier schafft Einheitlichkeit etwas mehr Reinlichkeit.

LESS (& Co.)

Bis vor ein paar Monaten habe ich noch überhaupt nichts von LESS oder Alternativen wie Sass gehört. Dies sind Spracherweiterungen von CSS, z.B. um Variablen und Mixins.

Hier ein kleines Beispiel mit LESS:

less-basics

Wie Variablen funktionieren, sollte man wohl keinem Programmierer erklären müssen. Z.B. können häufig verwendete Theme-Colors in Variablen wie @darkStrip abgelegt werden und dann an mehreren Stellen im LESS-Stylesheet wiederverwendet werden.

Ein Mixin kopiert alle Eigenschaften einer CSS-Klasse in eine andere. In dem Ausschnitt wird die Klasse header-view-port um die Eigenschaften der Klasse viewport erweitert. So können Redundanzen im CSS stark verringert werden. Mixins sind also noch mächtiger als einzelne Variablen.

Außerdem können CSS-Klassen hierarchisch ineinander geschachtelt werden, z.B. so dass die Struktur der Styles auch die Struktur des HTMLs wiederspiegelt. Folgenden Ausschnitt LESS finde ich dabei äußerst gut lesbar:

crunch

Die Scopes haben übrigens auch den Vorteil, dass Namenskonflikte innerhalb des CSS und damit ungewollte Design-Effekte sehr unwahrscheinlich werden.

Die Integration von LESS in ein Projekt ist übrigens ganz einfach, denn LESS wird einfach in CSS konvertiert. Es gibt Ansätze dies mittels Javascript zur Laufzeit im Browser, zur Laufzeit im Server oder zur Compile-Zeit auf der Entwicklungsmaschine zu konvertieren. Ich würde aber von diesen Ansätzen aus Produktivitäts- bzw. Performancegründen abraten. Ich finde es am einfachsten einen Editor zu verwenden, der beim Speichern einer LESS-Datei automatisch eine CSS-Datei erzeugt.

Visual Studio 2013 bringt übrigens von Haus aus einen Editor für LESS mit! Allerdings hat Microsoft vergessen einen to-CSS Konverter mitzuliefern, wobei es Erweiterungen für Visual Studio gibt, die das nachliefern.

Als Stand-Alone Tool kann ich Crunch absolut empfehlen. Hier muss ich lediglich STRG+ENTER drücken und fertig ist das CSS!

Modularisierung

Durch eine Modularisierung im CSS schafft man nicht nur mehr Klarheit, sondern geht auch Namenskonflikten aus dem Weg. CSS bietet dafür von Haus aus eine Art Namespacing an.

Gegeben sei z.B. eine Website, die eine Produkt-Detailseite und eine News-Detailseite enthält. Auf beiden Seiten gibt es eine Favoritenfunktion, wobei die Links unterschiedliche Styles haben.

Modularisiert kann man das wie folgt abbilden:

<div class="product-detail-page">
  ...
  <a class="add-to-fav" href="...">Add to fav</a>
</div>

...
<div class="news-detail-page">
  ...
  <a class="add-to-fav" href="...">Add to fav</a>
</div>

So können jetzt zwei saubere Styles dafür entworfen werden (auch ohne LESS, wobei es damit noch schöner wird)

.product-detail-page .add-to-fav {

   color: red;

}

.news-detail-page .add-to-fav {

  color: black;

}

Natürlich hätte man auch folgende HTML-Struktur wählen können…

<div>
  ...
  <a class="add-product-to-fav" href="...">Add to fav</a>
</div>

...
<div>
  ...
  <a class="add-news-to-fav" href="...">Add to fav</a>
</div>

Und dazu folgendes CSS:

.add-product-to-fav {

   color: red;

}

.add-news-to-fav {

  color: black;

}

Aber dieses CSS ist “flach” und bei vielen tausenden Zeilen CSS ist es dann nicht einfach Ordnung zu halten. Mit der wie oben beschriebenen Modularisierung ist dies einfacher realisierbar, wenn man die Stile innerhalb eines “Modules” anordnet.

Natürlich gibt es modulübergreifende Common Styles. Hier gilt aber aus meiner Sicht Folgendes: Erst einmal spezifisch innerhalb eines Modules definieren, später ggf. verallgemeinern (induktives Vorgehen).

Styles für einzelne Module sollte man in separate Dateien auslagern, im Extremfall kann man sogar für jede einzelne Page ein separates (LESS-)Stylesheet definieren.

Eine einzelne Stylesheet-Datei kann dann 100 oder 500 Zeilen enthalten, aber wohl kaum 5.000!

Bundling

Damit Websites performant laden, ist es wichtig viele kleine Dateien zu vermeiden. Entsprechend der mir beschriebenen Modularisierung wäre aber das Gegenteil erreicht. Allerdings ist es problemlos möglich die einzelnen Dateien wieder zu einer großen Datei zusammenzufügen. Das ist unter dem Namen Bundling bekannt.

ASP.NET MVC bietet das Bundling beispielsweise auf äußerst simple Art und Weise und standardmäßig integriert an. Als Tipp sei hier angemerkt, dass ganze Verzeichnisse inkludiert werden können:

bundles.Add(new StyleBundle("~/Content/css").Include(
                      "~/Content/bootstrap.css",
                      "~/Content/site.css").IncludeDirectory(
                      "~/Content/Site/", "*.css", true));

Fazit

Die Zutaten für sauberes CSS sind überall zu haben und erfordern nicht einmal besondere Fertigkeiten.