Webkrauts Logo

Webkrauts Webkrauts Schriftzug

- für mehr Qualität im Web

Effiziente CSS-Entwicklung mit Sass und Compass (Teil 2)

Effiziente CSS-Entwicklung mit Sass und Compass (Teil 2)

Im zweiten Teil über Sass und Compass stellt Mathias Schäfer die fortgeschrittenen Sprachtechniken vor. Die CSS-Werkzeuge bieten einen Komfort, den CSS ohne Hilfsmittel vermissen lässt. Mit Sass und Compass lässt sich umfangreicher Code strukturieren und CSS3 browserübergreifend einsetzen.

Im ersten Teil ging es um die Grundlagen von Sass und Compass: CSS Präprozessoren, die Installation, Verschachtelungen und Variablen. Der zweite Teil widmet sich fortgeschrittenen Sprachtechniken.

Mixins mit @include

Sass-Mixins ermöglichen das Definieren von Vorlagen, die beim Einbinden eine oder mehrere Deklarationen in die gegenwärtige Regel einfügen. Ein Mixin ist mit einer wiederverwendbaren Funktion vergleichbar, die auch Parameter als Variablen entgegennehmen kann.

Auf diese Weise könnt ihr wiederkehrende Muster zentral auslagern und an vielen Stellen einfach einbinden, anstatt sie bei jeder Anwendung zu wiederholen. Die Compass-Bibliothek stellt einen großen Fundus an Mixins dar, insbesondere für CSS3-Techniken. Diese bindet ihr mit der @include-Anweisung ein:

  1. .progress-bar {
  2.   $color: #ddd;
  3.   $height: 10px;
  4.   border: 1px $color solid;
  5.   @include border-radius(floor($height / 2) + 1px);
  6.   span {
  7.     background: $color;
  8.     display: block;
  9.     height: $height;
  10.     width: 0;
  11.     @include single-transition(width, 0.5s);
  12.   }
  13. }

Hier werden zwei Compass-Mixins verwendet, um CSS3-Features einfach einzubinden: border-radius sowie single-transition. Bei dem Beispiel handelt es sich um einen Fortschrittsbalken. Die Breite des inneren span-Elements wird mit JavaScript gesetzt. Durch die CSS3-Transition wird der Fortschrittsbalken automatisch animiert.

Das Definieren eigener Mixins ist ebenfalls möglich:

  1. @mixin off-left {
  2.   position: absolute;
  3.   left: -9999px;
  4.   width: 0;
  5.   height: 0;
  6.   font-size: 0;
  7.   overflow: hidden;
  8. }

Der obige Code definiert ein off-left-Mixin. Off-left ist eine bewährte Accessibility-Technik, um Inhalte für normale Browser zu verstecken, während sie von Screenreadern und anderer assistiver Software ausgegeben werden. Ein Anwendungsbeispiel:

  1. .js .accessible-fallback {
  2.   @import off-left;
  3. }

Bei aktiviertem JavaScript erhält das body-Element die Klasse js. Dadurch weden Elemente der Klasse accessible-fallback ausgeblendet, deren Inhalt bleibt jedoch für Screenreader zugänglich (siehe auch Grundregeln für zugängliches JavaScript).

Vererbung und Objektorientierung mit @extend

Eines der herausragenden Features von Sass ist die Vererbung von einem Selektor zum anderen. Damit lässt sich objektorientiertes CSS umsetzen, ohne das HTML mit unzähligen Klassen zu verschmutzen. Nachdem ein allgemeines Basismodul definiert wurde, reicht eine @extend-Anweisung aus, um ein spezifisches Modul auf dessen Regeln aufzubauen. Alle Formatierungen für das Basismodul gelten somit auch für das spezifische Modul. Auch verschachtelte Regeln werden vererbt. Ein Beispiel:

  1. // Allgemeines Box-Modul
  2.  
  3. .box {
  4.   border: $stream-border-width solid $box-border-color;
  5.   margin: 0 auto ($std-padding * 2);
  6.   padding: $std-padding;
  7.   background-color: $box-background-color;
  8.   /* … weitere verschachtelte Regeln … */
  9. }
  10.  
  11. // Spezifisches Modul in einer anderen Datei
  12.  
  13. .stream-item {
  14.   @extend .box;
  15.   background: white image-url("mp-thumb.png") no-repeat 11px 11px;
  16.   padding: 0;
  17.   position: relative;
  18. }

Damit wird eine komfortable Modularisierung möglich, wie sie aus Programmiersprachen bekannt ist. @extend ist oftmals besser als @mixin, da die Deklarationen im generierten CSS nicht wiederholt werden, der Code also sehr kompakt bleibt.

Beim Übersetzen in CSS wird die Vererbung sehr einfach gelöst: Der Selektor der erbenden Regel wird in den Selektor der erbenden Regel aufgenommen, dasselbe bei verschachtelten Regeln. Obiger Code erzeugt demnach folgenden Regeln:

  1. .box, .stream-item {}
  2. .stream-item {}

Man sollte sich dieser Funktionsweise bewusst sein, denn das »Hochziehen« im generierten CSS ändert die Reihenfolge der Regeln. In der Praxis bereitet das erfahrungsgemäß nur selten Probleme.

Mehrfachvererbung ist möglich und damit das beliebige Zusammenbauen aus anderen Modulen:

  1. .si-read-on a {
  2.   @extend .pushbutton;
  3.   @extend .blue-button;
  4.   @extend .button-with-arrow;
  5. }

Hier werden die Formatierungen von drei Modulen geerbt. Es handelt sich um einen blauen Button mit Pfeil-Symbol.

Zusammenfassen von mehreren Stylesheets

Beim Entwickeln hat es sich eingebürgert, der Übersicht halber die Regeln auf verschiedene Stylesheet-Dateien aufzuteilen. In einem Stylesheet sind verwandte Regeln gruppiert, z.B. für die Basis-Typographie oder für ein in sich geschlossenes Modul. Bei umfangreichen Websites können so dutzende Dateien zusammenkommen. Beim Ausliefern der Stylesheets in der Live-Umgebung wirken sich viele HTTP-Anfragen jedoch nachteilig auf die Performance aus. Daher werden die vielen kleinen CSS-Dateien üblicherweise zu einer großen zusammengefasst und wahlweise komprimiert.

Sass unterstützt das Zusammenfassen von Stylesheets von Haus aus. Dazu erweitert Sass die Bedeutung der @import-Anweisung von CSS: Eine .scss-Datei, deren Name mit einem Unterstrich beginnt, wird beim Übersetzen direkt eingebunden und nicht als gesonderte Datei übersetzt. Folgendes Stylesheet main.scss bindet verschiedene dieser sogenannten Partials ein:

  1. // Reset and variables
  2. @import 'reset';
  3. @import 'variables_mixins';
  4.  
  5. // Typo and layout
  6. @import 'typo';
  7. @import 'layout';
  8.  
  9. // Reusable modules
  10. @import 'topics';
  11. @import 'buttons';
  12. @import 'tabs';

Heraus kommt nur eine Datei main.css, die den übersetzen Code aller importierten Partials (_reset.scss, _variables_mixins.scss, _typo.scss usw.) enthält.

Sass unterstützt verschiedene Formatierungen des generierten CSS-Codes. Diese reichen von einem für Menschen lesbaren Stil mit viel Weißraum und Kommentaren zu einem komprimierten Stil, bei dem Zeilenumbrüche und Einrückungen entfernt wurden. Beim Entwickeln bietet sich erstere, in der Produktivumgebung letztere an, damit die zu übertragene Datenmenge möglichst klein ist.

Übersichtliche Alternativsyntax

Die obigen Beispiele verwenden die SCSS-Syntax (»Sassy CSS«), eine Erweiterung von CSS. Neben dieser gibt es eine Alternativsyntax, die die Dateiendung .sass verwendet. Dieses Format kommt ohne geschweifte Klammern und Semikola aus, dafür müssen Regeln und Deklarationen streng mit Zeilenumbrüchen getrennt werden und die Einrückung bekommt eine Bedeutung.

Bei .scss und normalem CSS ist das Trennen und Einrücken von Deklarationen nur eine Coding-Konvention, bei .sass ist es ein strenges Erfordernis. Die Anzahl der verwendeten Leerzeichen pro Einrückungsebene ist dabei frei wählbar. Es können auch Tabulatoren benutzt werden. Entscheidend ist, dass die Einrückungen einheitlich und stimmig sind.

Die obigen .scss-Beispiele verwenden bereits eine konsistente Einrückung mit zwei Leerzeichen. Daher müssen bloß Klammern und Semikola entfernt werden, um sie in .sass umzuwandeln:

  1. .progress-bar
  2.   $color: #ddd
  3.   $height: 10px
  4.   border: 1px $color solid
  5.   @include border-radius(floor($height / 2) + 1px)
  6.   span
  7.     background: $color
  8.     display: block
  9.     height: $height
  10.     width: 0
  11.     @include single-transition(width, 0.5s)

Sass überlässt dem Entwickler die Wahl der Schreibweise. Die .scss-Syntax hat den Vorteil, dass bestehende CSS-Dateien nur umbenannt werden müssen. Die .sass-Syntax ist aufgrund der fehlenden Trennzeichen einfacher zu schreiben und durch mehr Weißraum übersichtlicher. Sie zwingt dazu, gewisse Formatierungskonventionen anzuwenden.

»Mit Sass macht CSS wieder Spaß!«

Dies ist nur eine kleine Auswahl der Fähigkeiten von Sass, die euer Interesse wecken soll. Sass mag auf Frontend-Entwickler, die mit Kommandozeilen-Programmen sowie Objektorientierung wenig Erfahrung haben, zunächst ungewohnt und abschreckend wirken. Tatsächlich besitzt Sass viele Merkmale einer Programmiersprache und entsprechende Vorkenntnisse sind hilfreich. Es bedarf einiger Zeit, um Sass und Compass einzurichten und deren Einsatz zu erlernen.

Nach dieser Einarbeitung möchte man die Zeitersparnis beim Entwickeln allerdings nicht mehr missen. In unserer Firma haben sich Sass, Compass und andere CSS-Präprozessoren als unverzichtbar erwiesen. Schon bei kleineren Projekten verbessert deren Nutzung die Produktivität und die Codequalität, da auf eine ausgereifte, regelmäßig aktualisierte Bibliothek zurückgegriffen wird. Bei größeren Projekten führt insbesondere die gekonnte Verwendung von @mixin und @extend zu besser strukturiertem und wartbarem Code.

Sass entstammt zwar dem Ruby-Umfeld, benötigt jedoch nicht notwendig eine serverseitige Ruby-Unterstützung. Daher ist Sass im Grunde bei Webanwendungen in allen Programmiersprachen einsetzbar, auch bei rein statischen Websites.

Weiterführende Links

Kommentare

Bertram Simon
am 05.12.2011 - 09:38

Hallo Mathias,

sehr schöner Artikel, den ich gerne schon vor einem Jahr gelesen hätte.

Ich würde gerne noch ergänzen, dass Compass = SASS plus Templates plus Tools bedeutet. Am Anfang konnte ich nicht so richtig verstehen, wo der Unterschied ist, weil ich nur auf den Syntax geachtet habe.

Ein sehr großer Vorteil bei Compass ist das automatische Überwachen der Source-Files via

compass watch projekt

Dadurch wird die komplette Haupt-CSS-Datei kompiliert, auch wenn sich nur eine untergeordnete Import-Datei ändert.

Liebe Grüße

Bertram

Permanenter Link

Gunnar Bittersmann
am 05.12.2011 - 10:22

border-radius ist vielleicht kein gelungenes Beispiel für ein Compass-Mixin (mehr). Inzwischen verstehen alle Browser die prafixlose CSS3-Eigenschaft; -*-border-radius möchte man im generierten CSS nicht mehr haben.

Zum off-left-Mixin wäre anzumerken, dass man es gleich richtig[tm] machen sollte, bevor es einem bei einer RTL-Seite um die Ohren fliegt (siehe Folie 11 aus meinem
Multilingual-Web-Vortrag (PDF, 1 MB)). In dem Fall muss man den Inhalt rechts positionieren, und dann stimmt auch der Name des Mixins nicht mehr. (Benenne nie nach der Darstellung, hehe.)

„Die .sass-Syntax ist […] einfacher zu schreiben […]. Sie zwingt dazu, gewisse Formatierungskonventionen anzuwenden.“

Das ist für mich ein Widerspruch. Zwang, Formatierungskonventionen anzuwenden ≠ einfacher zu schreiben.

Auch „durch mehr Weißraum übersichtlicher“ sehe ich nicht gegeben; man kann beides gleich übersichtlich schreiben. Bei der SCSS-Syntax kommen lediglich die geschweiften Klammern hinzu; dabei gewinnt man die Freiheit, nicht an Formatierungskonventionen gebunden zu sein. Geschweifte Klammern ist man von CSS und Sprachen wie JavaScript sowieso gewöhnt. (Ich sagte bewusst nicht C oder PHP, weil „man“ hier Frontend-Entwickler meint.) Sucht man nach Vergleichen zwischen SASS und LESS, findet man haufenweise ältere Kommentare, die bemängeln, dass die SASS-Syntax ungewohnt anders ist (damals gab es die SCSS-Syntax noch nicht). Glücklicherweise hat sich das geändert.

In den Links wird das FireSass-Plugin erwähnt, dessen Bedeutung ich nochmal unterstreichen möchte. Ohne dieses zeigt Firebug die Zeilennummer einer Regel im automatisch generierten CSS, die aber uninteressant ist. Von Interesse ist ja, wo die Regel im vom Entwickler geschriebenen Quelltext steht: Dateiname des SASS/SCSS-Quelltextes und die Zeilennummer dort. Genau das tut das Plugin, wenn die Option --debug-info gesetzt ist (was man allerdings nur zum Testen tun sollte).

Permanenter Link

Gunnar Bittersmann
am 05.12.2011 - 10:26

@Bertram: Das automatische Überwachen der Quelldateien und automatische Neugenerieren des CSS bei Änderungen auch von importierten Dateien funktioniert auch bei SASS ohne Compass.

Permanenter Link
Jens Grochtdreis

Jens Grochtdreis (Webkraut)
am 05.12.2011 - 14:23

Bei Google+ gibt es zu diesem Artikel eine interessante Diskussion. Leider hat sie nicht hierher gefunden.

Permanenter Link

Stefan Walter
am 05.12.2011 - 15:58

Schöne Übersicht über SASS/Compass, vielen Dank dafür.

Was ich auch immer wieder praktisch finde, sind die Color-Funktionen von SASS, mal eben ohne ColorPicker oder größere Kaliber die Sättigung zurückdrehen oder ähnliches. Mehr dazu z.b. hier:

Referenz

Controlling Color with SASS color functions

Permanenter Link
Mathias Schäfer

Mathias Schäfer (Autor)
am 06.12.2011 - 14:03

@Gunnar:

»Zwang, Formatierungskonventionen anzuwenden ≠ einfacher zu schreiben.« – Die Einfachheit kommt dadurch, dass man unnötige Trennzeichen weglassen kann, weil es klare Verschachtelungsregeln gibt. Bei .scss muss ich Trennzeichen einfügen *und* die gegenwärtigen Konventionen beachten. Bei .sass fällt dies ineinander, also ist es einfacher.

Dass sämtlichen Webentwicklern durch JavaScript und PHP Klammern mehr liegen, halte ich für einen Trugschluss. Sass stammt aus einem Umfeld, in dem Significant Whitespace vorherrscht (Ruby, Python, CoffeeScript, YAML usw.) Das ist eine ebenso große Community, für die die neue .scss-Syntax »ungewohnt anders« ist. Mit den beiden Syntaxen will man alle Communities erreichen. Das ist gut so. Es gibt für beide gute Argumente und keinen Grund, eine verbohrt abzulehnen.

Zu FireSass kann ich nur sagen, dass ich persönlich es nicht brauche, es daher nur in den Links erwähnt habe. Ich identifiziere Regeln nicht anhand der Zeilennummer, sondern anhand des Selektors. Unsere .sass-Stylesheets sind meist nicht länger als 100 Zeilen und bestehen nicht aus vielen Regeln. Da ist es nicht schwer, die fragliche Regel anhand des Selektors zu finden.

Permanenter Link

Gunnar Bittersmann
am 07.12.2011 - 11:35

@molily: Ja klar: Jedem Tierchen sein Pläsierchen! Zumindest, solange man alein am Stylesheet arbeitet. Im Team sollte man sich dann wohl besser auf SASS- oder SCSS-Syntax einigen.

Die Regel für den im generierten CSS vorhandenen Selektor foo bar baz ohne FireSass im Quelltext zu finden, stelle ich mir schwierig vor, wenn dort
bar {
foo }
}

geschrieben steht.

Permanenter Link

Gunnar Bittersmann
am 07.12.2011 - 11:41

Argl, wo ist die Vorschau-Funktion?

Ich versuch’s nochmal:

bar {
  foo & {
    baz {
      …
    }
  }
}

Permanenter Link

Bertram Simon
am 16.12.2011 - 11:20

Ich würde gerne mal eure Meinung zu den CSS3-Mixins lesen. Compass erstellt ja z. B. folgenden Output:

.border_tl{
-moz-border-radius-topleft: 0.5em;
-webkit-border-top-left-radius: 0.5em;
-o-border-top-left-radius: 0.5em;
-ms-border-top-left-radius: 0.5em;
-khtml-border-top-left-radius: 0.5em;
border-top-left-radius: 0.5em;
}

Als ich die Preview von Operas Dragonfly ausprobiert habe, wurden mir für obiges Konstrukt 4x ein Fehler ausgegeben. Gleiches müsste auch für FF, Chrome usw. gelten.

Hat das eigentlich irgendwelche Auswirkungen, z.B. auf die Geschwindigkeit? Wenn man im Extremfall eine CSS3-Galerie aufbaut, würde man box-shadow, text-shadow, border-radius, font-face, transitions, gradients usw. nutzen. Das bedeutet tausende von "Fehlern".

Liebe Grüße

Bertram

Permanenter Link
Mathias Schäfer

Mathias Schäfer (Autor)
am 16.12.2011 - 12:06

@Bertram: Browser ignorieren unbekannte Eigenschaften einfach. Das schreibt der CSS-Standard vor. Die Geschwindigkeitseinbußen des Einlesens von unbekannten Eigenschaften sind zu vernachlässigen. Es ist eher problematisch, dass das Stylesheet dadurch aufgebläht wird. Das kann man bei CSS3 aber nicht vermeiden, das ist auch kein Spezifikum von Sass/Compass. Wenn man keinen Präprozessor nutzt, kann man auf die vielen Eigenschaften mit Hersteller-Präfixen nicht verzichten, wenn man möchte, dass die CSS3-Styles browserübergreifend wirken.

Das Entwicklertool Opera Dragonfly gibt einem lediglich eine Warnung aus, um einen auf einen möglichen Fehler im CSS hinzuweisen. Diese Warnungen sind nur für Entwicker gedacht – an sich hat hat Opera keine Probleme mit CSS3-Eigenschaften mit nicht unterstützen Vendor-Prefixes.

Permanenter Link

Sven Wolfermann
am 18.12.2011 - 17:38

Wie Mathias, bin auch ich mittlerweile ein Fan von Compass, warum hab ich mal in einem Blog-Artikel zusammen gefasst: http://maddesigns.de/compass-sass-1472.html

Permanenter Link

Die Kommentare sind geschlossen.