Compass & SASS – CSS3 Adventskalender Tag 17

Natürlich beschäftigt sich der diesjährige CSS3 Adventskalender auch mit dem Thema SASS & Compass. Was SASS & Compass so effizient macht beim Schreiben von CSS hat Mathias Schäfer (molily) bereits sehr umfassend im Webkrauts-Adventskalender-Artikel „Effiziente CSS-Entwicklung mit Sass und Compass“ (Teil 1, Teil 2) gezeigt.

Neue Techniken bringen natürlicherweise auch viel Diskussion mit sich. Und nur weil man einen Pre-Processor wie SASS verwendet, schreibt man nicht automatisch besseres CSS. Es muss schon ein gewisses Verständnis von CSS vorhanden sein, damit SASS, LESS, Stylus, Closure und MyNewCssPreProcessor™ auch effizient eingesetzt werden kann.

Leichter Einstieg

Durch die neue Schreibweise SCSS (“Sassy CSS”) wurde zudem der Einstieg in SASS erleichtert. Das hilft Einsteigern mit bestehenden Code die ersten Features von SASS auszuprobieren und so schnellere Erfolge zu erzielen.

Bestehendes CSS in SCSS konvertieren (geht auch zu SASS und auch von SASS zu SCSS,…)

# Convert CSS to SCSS
$ sass-convert style.css style.scss

Das wird über das jeweilige Kommandozeilen-Tool gemacht, gibt es aber auch online. Zur Installation von SASS und Compass gibt es auch zahlreiche Anleitungen im Netz, auch für Windows oder als App. Das sollte also kein Problem darstellen.

Einige nützliche Beispiele habe ich im Folgenden mal zusammen getragen. Aktuell starte ich meine Projekte mit dem Starter-Kit von xtine, das die HTML5 Boilerplate, Compass, SASS und normalize.css schon mitbringt (compass-sass-html5boilerplate).

Schön finde ich die Import-Funktion von SASS, so lassen sich gesplitete CSS (SASS)-Dateien zu einer zusammenfüren.

@import "modules/base";
@import "partials/header", "partials/footer";

Dabei werden Dateien, die mit Unterstrich beginnen direkt ins fertige CSS kompiliert, z.B. _base.scss, wo hingegen Dateien ohne Unterstrich, z.B. base.scss zusätzlich als separate CSS-Datei (z.B. base.css) durch den Watch-Prozess angelegt werden.

Partials können auch in Anweisungen importiert werden:

@media only screen and (min-width: 320px) {
  @import "partials/up320";
}

Elternselektor

Die Selektierung von Elternelementen ist für mich ebenfalls unschlagbar

article h1 {
  font-size: 2em;
	
  .index & {
    font-size: 1.6em;
  }
}

wird zu:

article h1 {
  font-size: 2em;
}
.index article h1 {
  font-size: 1.6em;
}

So kann direkt in der Anweisung eine andere Schriftgröße für H1 auf der Startseite vergeben werden

Compass – Multifunktions-Tool

Bild von http://sonspring.com/journal/sass-for-designers

Meiner Meinung nach macht SASS erst mit dem CSS-Framwork Compass richtig Sinn. Compass bringt eine Vielzahl von Funktionen und Mixins mit, die das Schreiben von CSS erleichtern. Das o.a. Bild zeigt es meiner Meinung nach sehr treffend. Gerade im CSS3-Bereich spielt Compass seine Stärken aus, hier ist ein großes Set an CSS3-Mixins bereits enthalten und werden ständig nachgepflegt.

Ein dickes Feature ist sicherlich das Generieren von Sprites-Grafiken (warum Sprites?), dazu gibt es ein umfangriches Tutorial auf der Compass-Website.

CSS3 Mixins

Linear-Gradients sind nach wie vor mühsehlig, für alle Browser müssen Anweisungen mit Vendor-Prefixe geschrieben werden, aktuell sieht ein simpler cross-browser Linear-Gradient so aus:

.gradient { 
	
  background-color: yellow; /* Fallback Color */
  background: -webkit-gradient(linear,left top,left bottom,from(yellow),to(blue));
  background: -webkit-linear-gradient(top, yellow 0%, blue 100%); 
  background:    -moz-linear-gradient(top, yellow 0%, blue 100%); 
  background:     -ms-linear-gradient(top, yellow 0%, blue 100%); 
  background:      -o-linear-gradient(top, yellow 0%, blue 100%); 
  
  /* aktueller W3C Standard, bisher nicht implementiert */
  background:         linear-gradient(to bottom, yellow 0%, blue 100%);
  
}
mit Compass sieht die Anweisung so aus:
.gradient {
  @include background(linear-gradient(top, yellow, blue));
}

zusätzlich könnte man noch SVG-Support für IE9 und ältere Opera über $experimental-support-for-svg: true; aktivieren, sowie die älteren Internet Explorer (IE6-IE8) mit Filtern ausstatten:

.gradient {
	$experimental-support-for-svg: true;
	@include background(linear-gradient(top, yellow, blue));
	
	// for older IEs
	.oldie & {
		background-color: yellow;
		@include filter-gradient(yellow, blue, vertical);
	}
}

das wird dann wie folgt kompiliert

.gradient {
  background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0i.....');
  background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ffff00), color-stop(100%, #0000ff));
  background: -webkit-linear-gradient(top, #ffff00, #0000ff);
  background: -moz-linear-gradient(top, #ffff00, #0000ff);
  background: -o-linear-gradient(top, #ffff00, #0000ff);
  background: -ms-linear-gradient(top, #ffff00, #0000ff);
  background: linear-gradient(top, #ffff00, #0000ff);
}
.oldie .gradient{
  background-color: yellow;
  *zoom: 1;
  filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#FFFFFF00', endColorstr='#FF0000FF');
}

Globale Variablen wie $experimental-support-for-svg werden für das gesammte Compass-Projekt gesetzt (wie der Name schon sagt). Wenn man im nächsten Gradient keinen SVG-Support wünscht, müsste man $experimental-support-for-svg in der Anweisung wieder auf false setzen. $experimental-support-for-khtml: false; kann eigentlich als Default in _base.scss gesetzt werden. Man kann auch den Support von IE6 oder IE7 deaktivieren, wenn das für das Projekt nicht nötig ist:

// _base.scss
$experimental-support-for-khtml: false;
$legacy-support-for-ie6: false;
$legacy-support-for-ie7: false;

Aber nicht alle CSS3-Mixins sind zu empfehlen, border-radius ist überfrachtet und kann mittlerweile auch ohne Vendor-Präfix eingesetzt werden.

.box {
  @include border-radius();
}

wird zu

.box {
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  -o-border-radius: 5px;
  -ms-border-radius: 5px;
  -khtml-border-radius: 5px;
  border-radius: 5px;
}

Hier ist einiges zu viel und zudem falsch (-ms-border-radius). Hier reicht also einfach:

.box {
  border-radius: 5px;
}

Nützlich ist auch das Mixins für Links. Wenn man Links mit alle dynamischen Pseudoklassen stylt, sieht das mit SASS so aus:

$color-main: #0089B3;
a {
	text-decoration: none;
	color: $color-main;
	&:hover {
		text-decoration: underline;
		color: darken($color-main, 10%);
	}
	&:focus {
		color: darken($color-main, 10%);
	}
	&:active {
		color: invert($color-main);
	}
	&:visited {
		color: darken($color-main, 30%);
	}
}

In Compass kann man daraus einen Zweizeiler machen:

a {
  @include hover-link;
  @include link-colors(
    $color-main, 
    darken($color-main, 10%), 
    invert($color-main), 
    darken($color-main, 30%), 
    darken($color-main, 10%)
  );
  // hier zur Übersichtlichkeit mehrzeilig
}

wird zu

a { text-decoration: none; color: #0089b3; }
a:hover { text-decoration: underline; }
a:visited { color: #00141a; }
a:focus { color: #006280; }
a:hover { color: #006280; }
a:active { color: #ff764c; }

Ja, Compass fasst :hover und :focus nicht zusammen, aber das kann man sicherlich verschmerzen – genau solche Beispiel sind es die Kritiker dann auf den Plan bringen…

Bild: http://sonspring.com/journal/sass-for-designers

Gerne bin ich bereit über Sinn und Unsinn in den Kommentaren zu diskutieren.

If-Bedingungen in CSS

$main-bg: #333;
.main {
  color: if($main-bg == #333, #fff, #000);
}

Jeder der ein wenig Programmierkenntnisse hat, wird das zu schätzen wissen. Wenn die Hintergrundfarbe #333 (dunkles grau) ist, dann ist die Textfarbe #fff (weiß), sonst #000 (schwarz). Klasse, oder?

Oder die Möglichekeit Überschriften in anderen Bereichen der Website, anders zu formatieren:

aside {
  #{headings(2,4)} {
    text-transform: uppercase;
  }
}

wird kompiliert zu

aside h2, aside h3, aside h4 {
  text-transform: uppercase;
}

Die Compass Image-Funktionen sind auch ganz toll:

header {
  background: image-url("header-bg.png");
  h1 {
    height: image-height("logo.png");
    width: image-width("logo.png");
    background: transparent inline-image("logo.png") no-repeat;
  }
}

So kann man mit image-height() und image-width() die Höhe und Breite des Logos automatisch einfügen, falls sich das Logo ändert, ändern sich auch automatisch die Höhe und Breite. Zudem kann man das Logo als inline-image() einfügen. Das Beispiel wird dann folgendermaßen kompiliert:

header {
  background: url('../img/header-bg.png');
}
header h1 {
  height: 185px;
  width: 140px;
  background: transparent url('data:image/png;base64,/9j/4AAQSkZJRgABAgAAZABkAAD....') no-repeat;
}

Plugins

Für Compass gibt es mittlerweile eine große Anzahl an Plugins, die das Framework erweitern. Eines hab ich total lieb gewonnen: Aaron Russell’s Plugin für den RGBA PNG Support – das erstellt für ältere Browser (IE6-IE8) transparente PNGs anhand der zugewiesenen RGBA-Farbe. Man installiert sich das Plugin und bindet es in das Compass config.rb File ein.

// require in config.rb
require "rgbapng"

Dann importiert man das Mixin in das SCSS und weist es wie folgt zu:

@import "rgbapng";
footer {
  @include rgba-background(rgba(#fff,0.25));
}

Das Plugin RGBAPNG legt dann eine Grafik im img-Folder an. Das generierte CSS:

footer {
  background: url('../img/rgbapng/ffffff40.png?1324100912');
  background: rgba(255, 255, 255, 0.25);
}

Wenn man den Alpha-Wert ändert, wird eine neue Grafik erstellt. Praktisch, oder?

Fazit

Für mich ist SASS & Compass eine Arbeitserleichterung geworden. Zudem werden einige Konzepte von SASS in die zukünftige CSS4 einfließen, wie Tab Artkins auf der diesjährigen Fronteers Konferenz in Amsterdam erwähnte (Video).
Ich hoffe ich konnte ein paar nützliche Beispiele für den Einsatz von Compass mit SASS liefern. Welche Erfahrungen habt ihr mit SASS & Compass gemacht? Habt ihr nützliche Mixins, verlinkt die in den Kommentaren. Werdet Ihr jetzt CSS-Preprozessoren verwenden?

18 thoughts on “Compass & SASS – CSS3 Adventskalender Tag 17”

  1. Danke für die Abhandlung … ich habe schon öfter überlegt, mir ein CSS-Framework Eigen zu machen, einfach um dieses ewige Getippe auf ein nötiges Minimum zu reduzieren … schließlich verwendet man ja bereits Snippets und fertige HTML-Wireframes, wieso sollte man sich beim CSS einen abkrampfen.

    Die Kritik an der Teilung von :hover und :focus kann ich nicht so ganz verstehen. Wieso sollte man die auch zusammenfassen? Wenn man für maus- und tastatursensitive Steuerung entwickelt, kann man für die „Mauser“ :hover verwenden … für leute, die sich durch ein Angebot via Tastatur tabben ist ganz praktisch, wenn man via :focus hier auch eine andere, kräftigere Auszeichnung (z.B. background hervorheben für die jeweiligen Links) nimmt.

    Von daher finde ich das dort ganz praktisch. Klar, man hätte evtl. eine Methode finden können, das, wenn man es explizit auch zusammenfassen kann.

    Frameworks helfen halt lediglich in der Reduzierung des benötigten Arbeitspensums … wie z.B. jQuery und Co. eine extreme Erleichterung sind … sie schleppen aber für die meisten Projekte halt einen massiven Overhead mit sich rum.

    Ergo ist vor Einsatz eines Frameworks die Frage zu stellen, was man damit machen will und ob es einen vertretbaren Benefit (Stichwort Rapid Prototyping) bringt, gegenüber dem manuellen Erstellen.

    Für mich bisher ein „Manko“ das man in den meisten Fällen verkraften kann.

    Just my 2ct :)

    René

  2. Ich werd mit diesen Systemen nicht warm. Es gibt zu viele, sie haben sich nirgends groß als Standard verbreitet. Ich würde keine großen Projekte mit sowas aufsetzen. Erstens schränkt das die Leute ein, die evtl. mit dran arbeiten müssen und zweitens: Was ist wenn das gewählte System irgendwann mal eingestellt wird?

    PS: Muss Compass auf dem Webserver laufen? Welcher Webserver hat schon Ruby?

  3. Compass kann lokal genutzt werden, kann aber auch mit Ruby direkt auf dem Server laufen. Wenn ein Projekt mal eingestellt werden sollte, kannst du wieder normales CSS schreiben, das wirst du ja nicht verlernen. Und gerade in größeren Projekten spielen SASS & Compass die Stärken aus, IMHO. Aber sicherlich ist das ein Lernprozess für das Team. Aber wir lernen doch gern was neues, oder?

  4. Danke für die Einführung. Ich versuche im Moment, mich in Compass einzuarbeiten, da kommen mir Artikel wie dieser gerade recht.

    Zum Thema if-Schleifen: http://www.if-schleife.de/
    Aber ich sehe, das hast du ja schon geändert. Ist nur noch nicht im Google-Reader angekommen. ;-)

  5. @Andi: Natürlich ist es dir freigestellt, ob du Präprozessoren wie SASS verwenden möchtest. Deine Argumentation kann ich aber irgendwie nicht nachvollziehen:

    > Es gibt zu viele, sie haben sich nirgends groß als Standard verbreitet.
    Es gibt als weit verbreitete Standards eigentlich nur SASS und LESS. SASS ist z.B. mittlerweile das Standardformat für aktuelle Ruby on Rails-Applikationen, LESS wird z.B. auch von Twitter produktiv verwendet (z.B. im Twitter-Bootstrap-Projekt). Für Node.js wurde Stylus von TJ Holowaychuk entwickelt (der auch schon einige andere sehr bekannte Frameworks für Node.js geschrieben hat), wobei die Verbreitung von Stylus noch sehr gering ist. Wenn du also nicht im Node.js-Bereich arbeitest, kann man das Framework momentan sogar noch vernachlässigen.

    > Erstens schränkt das die Leute ein, die evtl. mit dran arbeiten müssen
    In wiefern schränkt es die Leute ein? Es ist ein Superset von CSS und syntaktisch soweit identisch. Die Erweiterungen wie z.B. Mixins lehnen sich im Syntax an bestehende CSS-Features (@import, @media, etc.) an und sind schnell zu lernen. Du bist auch in der Anwendung sehr flexibel, so dass du Features nach und nach einsetzen kannst.

    Hinzu kommt, dass einige der Features, die heute mit SASS schon möglich sind, in die CSS-Spezifikationen übernommen wurden und in CSS4 enthalten sein werden. Man kann also sagen, dass man hier recht zukunftssicher arbeiten kann.

    > Was ist wenn das gewählte System irgendwann mal eingestellt wird?
    SASS, LESS und Stylus sind alle Open Source unter MIT-Lizenz und stehen auf GitHub zu Verfügung, können also problemlos eigenständig weiter entwickelt werden.

    > Muss Compass auf dem Webserver laufen?
    Nein, das ist nicht erforderlich.

    > Welcher Webserver hat schon Ruby?
    Wenn man mal von Billig-08/15-Hostern absieht, ist das kein Problem, das wird von vielen professionellen Anbietern schon angeboten, sobald du einen eigenen VServer hast, kannst du es auch problemlos selbst installieren.

    Du kannst es dir sogar NOCH einfacher machen: Es gibt mittlerweile kostenlose Tools für Windows und Mac, die dir die Installationsarbeit von SASS und Compass abnehmen und automatisch bei Änderungen am Source eine neue CSS-Datei kompilieren: z.B. CodeKit (Mac): http://www.webkrauts.de/2011/12/16/codekit-der-alleskoenner-unter-den-tools-fuer-frontendentwickler/ oder Scout (Mac/Windows): http://mhs.github.com/scout-app/.

  6. Es gibt noch mehr Nieten zu zählen: „Elternselektor“??

    „Die Selektierung von Elternelementen ist für mich ebenfalls unschlagbar.“ Für mich ist sie vor allem eins: in CSS 3 _unmöglich_.

    Ein Eltenelement zu selktieren hieße ja, bei das ‚foo‘-Element zu seleketieren, wenn es Eltenelement von ‚bar‘ ist. Andersrum wird’n Schuh draus: Man kann ‚bar‘ selktieren, wenn es Kind von ‚foo‘ ist.

    Mit dem Selektor ‚foo bar‘ tut man aber nicht (nur) das, sondern selektiert ‚bar‘ auch dann, wenn es (Ur)*enkel von ‚foo‘ ist.

    „Elternselektor“ ist doppelt falsch: zum einen stimmt die Richtung nicht, zum anderen muss es nicht Kind-, sondern Nachfahrenselektor heißen.

  7. Zugegeben, das Beispiel mit den Elternselektoren ist nicht ausschöpfend erklärt, aber so wird die Technik nunmal in SASS genannt (http://thesassway.com/intermediate/referencing-parent-selectors-using-ampersand). Nein, es gibt keine Möglichkeit mit CSS3 Elternelemente zu selektieren, aber es geht hier um SASS und Compass, da kann ich recht einfach mit dem Ampersand (&) dem Ruleset einen Selektor voranstellen um das Regelset um einen „Vorfahrenselektor“ zu erweitern. In meinem Beispiel ist es die Überschrift h1 innerhalb von article, die beim „Elternselektor“ .index kleiner ist, als auf anderen (Unter-)seiten.

  8. rgbapng – wenn man in einer windowsinstallation scout verwendet – wie lässt sich das plug intgrieren? Hab mir manuell das github Zip in den gems ordner geladen – nur wird es in der SCSS nicht gefunden. „File to import not found or unreadable: rgbapng.“ Muss man da die Load Paths anpassen? Wo sieht man im Github welches file wohin gehört..

  9. Ja klar, das war natürlich der erste Ansatz. Doch da brauche ich einen Zugriff auf das Download-Repository, oder? Scout ist bei mir in einem Offline Host installiert und kompiliert die CSS-Dateien auf ein guest-host Netzlaufwerk. Dieses lasse ich dann auf Änderungen überwachen und per FTP synchen. Bei Contao Plugins habe ich die XML zum entpacken, bzw aus der Ordnerhierarchie ist gut zu erkennen was wo hingehört, wenn ich offline außerhalb des Repository arbeite. MIt Scout bin jetzt schon soweit:

    .layouttest-article {
    background: png_base64(rgba(0, 0, 0, 0.2)); // <– ist wohl nicht Sinn der Sache, bzw. invalide ;-)
    background: rgba(0, 0, 0, 0.2);

    Nur sobald ich den require rgbapng in der config.rb setze, bekomme ich einen LoadError on line 1038 of org/jruby/RubyKernel.java: no such file to load — rgbapng.

    Wahrscheinlich ist es nur noch eine kleine Sache, die fehlt. Bin dankbar für jeden Hinweis und forsche weiter.

  10. „Ganz normal“ war die letzten Monate Scout für mich und ich würde mir wünschen dass das auch so bleibt ;-)

    „https://github.com/mhs/scout-app/wiki/Using-RubyGems-with-ScoutApp“

    ist vielleicht die Lösung, etwas umständlicher als erwartet vielleicht. Hoffe mal dass das irgendwie klappt.

Kommentare sind geschlossen.