tutorials.de Buch-Aktion 05/2012
RSS-Feed anzeigen

Code that sings

Mehr Spaß mit CSS dank Sass

Bewerten
von Matthias Reitinger am 28.06.09 um 00:23 (2814 Hits)
(Es folgt ein für dieses Blog untypischer Beitrag. Diesmal widme ich mich nicht der Sprache Ruby, sondern einer vor allem für Webdesigner interessanten Sprache, die allerdings in Ruby implementiert ist. Da diese Sprache fast so schön ist wie Ruby selbst, landet der Beitrag trotzdem hier )

Die Schwächen von CSS
So gut wie jeder Webdesigner hat sich sicher schon einmal über die ein oder andere Eigenheit von CSS geärgert.

Ein Beispiel gefällig? Will man eine bestimmte Grundfarbe an mehreren Stellen im Stylesheet verwenden, muss man diese an jeder Stelle voll ausschreiben. Entscheidet man sich, die Farbe später zu ändern, muss man jede dieser Stellen einzeln ändern. Besonders wenn man mehrere .css-Dateien verwendet, ist das ärgerlich. Wenn CSS doch nur das Definieren eigener Konstanten zulassen würde!

Ein weiteres Szenario: es sollen mehrere Stile definiert werden, die nur in <div id="special"> gelten. Dann muss man jedem Selektor ein #special voranstellen, um den Wirkungsbereich einzugrenzen. Bei 20 Stilen muss man also 20 mal #special tippen – ziemlich ätzend. Wenn CSS doch nur nicht so redundant wäre!

Letztes Beispiel: Größen in pixelgenauen Layouts setzen sich oftmals aus mehreren Komponenten zusammen. Hat man z.B. ein <div>, das zwei weitere <div>s mit fester Breite enthält und will/muss man für das äußere <div> die Breite explizit angeben, muss man die Breiten der beiden inneren <div>s addieren. Das kann man beim ersten Entwurf problemlos im Kopf oder mit dem Taschenrechner machen und das Ergebnis entsprechend in der .css notieren. Stellt sich nun später heraus, dass die inneren <div> nun doch eine andere Größe erhalten sollten, fängt die händische Rechnerei von vorne an. Ganz abgesehen davon, dass ohne Kommentare in der .css erst mal nicht klar ist wie der konkrete Wert zustande kommt. (Und mal ehrlich: wer kommentiert schon seine CSS-Dateien?) Wenn man in CSS doch nur einfache Berechnungen durchführen könnte!

Kommt euch irgendeines dieser Szenarien bekannt vor? Dann freut euch, denn all das gehört der Vergangenheit an, dank…

Syntactically Awesome Stylesheets (Sass)
Sass ist eine Meta-Sprache, die auf CSS aufsetzt und unter anderem die oben angedeuteten Schwächen von blankem CSS aufhebt. Dazu braucht man aber keinen speziellen Browser, da Sass in ganz normales CSS transformiert wird (z.B. durch das Kommandozeilentool sass). Mehr Funktionalität im Browser darf man sich von Sass also nicht erwarten, nur eine sehr viel angenehmere Methode, Stylesheets zu erstellen.

Wer die folgenden Beispiele selber nachvollziehen möchte, kann dies im Sass Lab tun (direkt im Browser, ohne Installation).

Syntax für Regeln
Sass verwendet für Selektoren und Attribute dieselbe Notation wie reines CSS. Der Unterschied liegt nur darin, dass in Sass Regeln nicht durch ein Paar von {}, sondern implizit über die Einrückung (zwei Leerzeichen) begrenzt werden. Außerdem benötigt man keine ; am Ende einer Attributzuweisung. Zum Beispiel:
CSS:
Code css:
1
2
3
4
5
6
7
8
#content {
  font-family: sans-serif;
  background: white;
}
 
#content p {
  width: 97%;
}
Sass:
Code css:
1
2
3
4
5
6
#content
  font-family: sans-serif
  background: white
 
#content p
  width: 97%

Darüber hinaus bietet Sass noch eine weitere Möglichkeit zur Notation von Attributen an: statt den Doppelpunkt hinter den Attributnamen zu setzen, kann man ihn auch direkt davor schreiben:
Sass:
Code css:
1
2
3
4
5
6
#content
  :font-family sans-serif
  :background white
 
#content p
  :width 97%
Der Vorteil hiervon liegt darin, dass man so eine Attributzuweisung visuell schneller als solche erkennen kann. Im Folgenden werde ich deshalb auch diese Notation verwenden.

Bisher ist noch nicht viel Spannendes passiert, außer dass man sich so etwas Tipparbeit sparen kann. Die Mächtigkeit von Sass wird in den nächsten Abschnitten erst deutlich.

Verschachtelte Regeln
Mit Sass kann man Regeln auch verschachteln. Eine Regel, die „innerhalb“ einer anderen Regel steht, wird als untergeordnet behandelt. Das heißt konkret, dass dem Selektor der inneren Regel der Selektor der äußeren vorangestellt wird. Unser bisheriges Beispiel ließe sich also auch so schreiben:
Sass:
Code css:
1
2
3
4
5
#content
  :font-family sans-serif
  :background white
  p
    :width 97%
Das funktioniert über beliebig viele Ebenen, sodass also auch folgendes möglich ist:
Sass:
Code css:
1
2
3
4
5
6
7
8
9
#content
  :font-family sans-serif
  :background white
  p
    :width 97%
    a
      :text-decoration none
      .extern
        :color red

Das daraus erzeugte CSS sähe dann so aus:
CSS:
Code css:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#content {
  font-family: sans-serif;
  background: white;
}
 
#content p {
  width: 97%;
}
 
#content p a {
  text-decoration: none;
}
 
#content p a .extern {
  color: red;
}
Ziemlich praktisch, oder nicht?

Präfixe für Attribute
Logisch zusammengehörende CSS-Attribute besitzen oft einen gemeinsamen Präfix, so zum Beispiel font-family, font-size, font-style usw. Sass bietet hier die Möglichkeit, Attributnamen zu schachteln:
Sass:
Code css:
1
2
3
4
5
#content
  :font
    :family sans-serif
    :size 90%
    :style normal
CSS:
Code css:
1
2
3
4
5
#content {
  font-family: sans-serif;
  font-size: 90%;
  font-style: normal;
}
Man spart sich dadurch einerseits wieder Tipparbeit, andererseits wird so optisch hervorgehoben, dass die Attribute eine Gemeinsamkeit aufweisen.

Selbstdefinierte Konstanten
In Sass lassen sich Konstanten definieren, die dann an beliebiger Stelle im Stylesheet eingesetzt werden können. Beispiel:
Sass:
Code css:
1
2
3
4
5
6
7
8
9
!base_color = #def
!contrast_color = #000
 
#content
  :color = !contrast_color
  :background-color = !base_color
  a
    :color = !base_color
    :background-color = !contrast_color
CSS:
Code css:
1
2
3
4
5
6
7
8
#content {
  color: #000;
  background-color: #def;
}
#content a {
  color: #def;
  background-color: #000;
}
So lässt sich die Redundanz von Informationen gegenüber blankem CSS reduzieren. Außerdem wird den Konstanten durch eine sinnvolle Benennung auch gleich noch eine Semantik zugewiesen.

Rechnen mit Größen und Farben
Sass kann auch einfache Berechnungen durchführen. Dies kann sowohl bei der Definition einer Konstante als auch beim Einsetzen passieren. Zum Beispiel:
Sass:
Code css:
1
2
3
4
5
6
7
8
9
10
!base_color = #def
!full_width = 960px
!half_width = !full_width / 2
 
#content
  :color = white - !base_color
  :background-color = !base_color
  :width = !full_width
  p .half-width
    :width = !half_width
CSS:
Code css:
1
2
3
4
5
6
7
8
#content {
  color: #210;
  background-color: #def;
  width: 960px;
}
#content p .half-width {
  width: 480px;
}
Wie man sieht, rechnet Sass bei Farben komponentenweise. Es kennt außerdem die Farbwerte zu den Standard-Farbnamen, sodass man auch direkt mit ihnen rechnen kann (wie im Beispiel bei der Berechnung der Komplementärfarbe). Mit Größenangaben lässt sich ebenso rechnen (+, -, *, %), solange die Einheiten übereinstimmen (100px + 10px funktioniert also, 100px + 1em dagegen nicht).

Weitere Features
In dieser kurzen Einführung wollte ich nur die wichtigsten Features von Sass erwähnen. Darüber hinaus unterstützt Sass beispielsweise noch Mixins (sozusagen Vorlagen von Attributen, die an beliebiger Stelle eingefügt werden können), Direktiven zum Import anderer Dateien (@import stlye.sass) und verschiedene Arten von Kommentaren. Für eine vollständige(re) Beschreibung der Sprache verweise ich auf die offizielle Dokumentation.

Installation von Sass
Wenn ihr jetzt Blut geleckt habt und Sass auf euerem eigenen Rechner installieren wollt, dann kommt für viele vielleicht erst mal ein Dämpfer: Sass ist in Ruby geschrieben, ihr benötigt also eine funktionierende Ruby-Installation auf euerem Rechner, um Sass verwenden zu können. Das ist aber halb so schlimm, denn für Windows gibt es den One-Click Ruby Installer und in den meisten Linux-Distributionen sollte Ruby über das Paketsystem installierbar sein. Achtet darauf, dass ihr auch Rubygems installiert (im Windows-Installationspaket enthalten). Um Sass zu installieren, reicht dann die Eingabe von[1]
Code :
1
gem install haml
in der Kommandozeile (beachtet, dass ihr dazu ggf. Administrator-/Rootrechte braucht).

Zur Transformation von Sass in CSS genügt dann die Eingabe von
Code :
1
sass input.sass output.css
wieder in der Kommandozeile. Dies kann auch mit Ruby-Mitteln automatisiert werden, sodass die .css automatisch erzeugt wird, sobald sich der Inhalt der .sass ändert. Falls Bedarf besteht, werde ich das auch noch näher erläutern. Einfach in einem Kommentar Bescheid sagen.

Und jetzt wünsche ich euch viel Spaß beim Experimentieren mit Sass!

– Matthias

[1]: Haml ist der Name einer weiteren Meta-Sprache, welche das Schreiben von HTML auf ähnliche Weise vereinfacht wie Sass für CSS. Sass ist ein Bestandteil von Haml, weswegen die Installation von Haml notwendig ist.

"Mehr Spaß mit CSS dank Sass" bei Twitter speichern "Mehr Spaß mit CSS dank Sass" bei Facebook speichern

Aktualisiert: 12.07.09 um 01:22 von Matthias Reitinger

Stichworte: css, sass
Kategorien
Programming

Kommentare

  1. Avatar von Sven Mintel
    Interessante Sache, sollte eigentlich nicht allzu schwer sein, das auch mit bspw. PHP umzusetzen ....ich werd das demnächst mal in der Praxis ausprobieren
  2. Avatar von modo
    Hallo Matthias
    ich bin ein Ruby Greenhorn und hätte noch Fragen.

    Habe Ruby und haml installiert, soweit alles ok.
    Meine Frage,
    1.Die Dateien (sass) wo muss ich sie abspeichern um sie nach in css konvertieren zu können?
    2. Ich nehme an ich muss die datei als .sass speichern.

    Sorry für die vielleicht dämmliche Fragen, aber wie gesagt ich bin ein völliger RubyGreenhorn.
    Muss aber sagen die Sache ist sehr interessant. Werde mich in Zukunft mehr mit Ruby+ CO beschäftigen.

    Danke dir für den Rat
    Gruss Modo
  3. Avatar von Matthias Reitinger
    @Sven Mintel: Eine PHP-Implementierung von Sass wäre eine tolle Sache. Eine Umsetzung von Haml in PHP gibt es ja bereits.

    @modo: Du kannst die .sass-Dateien abspeichern wo du willst. Idealerweise speicherst du die Datei aber in das Verzeichnis, in das später auch die .css kommen soll. Dadurch sparst du dir Tipparbeit auf der Konsole. Auch die Endung kannst du frei wählen, allerdings hat sich .sass schon halbwegs eingebürgert.
  4. Avatar von hela
    Danke für diesen Beitrag - selbstdefinierte Konstanten habe ich mir schon immer gewünscht!
  5. Avatar von D34DL1NES
    Zitat Zitat von hela
    Danke für diesen Beitrag - selbstdefinierte Konstanten habe ich mir schon immer gewünscht!

    Es sind ja vorallem sogar Variablen, bsw. kann man ja mit ihnen rechnen, eine enorme Erhöhung der Effizienz, Danke!

    Ich fande es sehr cool wenn du nochmal die Automatisierung erklären könntest, ich hab nämlich keine Ahnung von ruby...:/
    Aktualisiert: 21.07.09 um 06:12 von D34DL1NES
  6. Avatar von Matthias Reitinger
    Zitat Zitat von D34DL1NES
    Ich fande es sehr cool wenn du nochmal die Automatisierung erklären könntest, ich hab nämlich keine Ahnung von ruby...:/
    Zuerst mal sorry für die späte Antwort - ich hatte deinen Kommentar schlicht übersehen.

    Zur Automatisierung kann das Skript von Pragmatic Automation verwendet werden:
    Code ruby:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    
    if ARGV.size < 2
      puts "Usage: stakeout.rb <command> [files to watch]"
      exit 1
    end
     
    command = ARGV.shift
    files = {}
     
    ARGV.each do |arg|
      Dir[arg].each { |file|
        files[file] = File.mtime(file)
      }
    end
     
    loop do
      sleep 1
      changed_file, last_changed = files.find { |file, last_changed|
        File.mtime(file) > last_changed
      }
      if changed_file
        files[changed_file] = File.mtime(changed_file)
        puts "=> #{changed_file} changed, running #{command}"
        system(command)
        puts "=> done"
      end
    end
    Der Aufruf erfolgt dann z.B. mit
    Code :
    1
    
    stakeout.rb "sass style.sass style.css" style.sass

    Grüße, Matthias