Was ist Sass?
Sass steht für Syntactically Awesome Style Sheets. Es ist ein CSS-Präprozessor – eine Sprache, die einfaches CSS um Programmierfunktionen erweitert und in Standard-CSS kompiliert wird, das von Browsern verstanden werden kann. Wenn Sie schon einmal Farbwerte wiederholt, Media Queries dupliziert oder sich durch hunderte Zeilen flachen CSS gearbeitet haben, ist Sass das Werkzeug, das diese Probleme löst.
Sass wurde 2006 von Hampton Catlin entwickelt und war der erste CSS-Präprozessor, der eine breite Akzeptanz fand. Es führte Konzepte aus allgemeinen Programmiersprachen – Variablen, Nesting, Funktionen, Schleifen und Module – in die Welt der Stylesheets ein. Heute bildet es die Grundlage für Projekte wie Bootstrap, Foundation und zahllose Design-Systeme.
Am besten betrachten Sie Sass als CSS mit einem Werkzeugkasten. Sie schreiben .scss- oder .sass-Dateien unter Verwendung von Sass-Features, lassen diese durch einen Compiler laufen und erhalten einfache .css-Dateien zurück, die der Browser laden kann. Es gibt keine Runtime-Kosten. Die gesamte Power liegt in Ihrem Development-Workflow.
Sass vs CSS: was ändert sich?
Reines CSS ist eine deklarative Sprache – man beschreibt, wie Elemente aussehen sollen, aber man kann keine Abstraktionen erstellen, Logik wiederverwenden oder Code über das Aufteilen in separate Dateien hinaus organisieren. Sass behebt jede dieser Einschränkungen:
| Funktion | Reines CSS | Sass |
|---|---|---|
| Variablen | Custom properties (--var) |
$variable mit vollständigem Scoping |
| Nesting | Basis (mittlerweile in CSS) | Ausgereift, mit Parent-Selektoren (&) |
| Wiederverwendbarkeit | Copy-Paste oder Utility-Klassen | Mixins, Funktionen und Extends |
| Organisation | Nur @import |
@use, @forward, Partials |
| Logik | Keine | @if, @each, @for, @while |
| Mathematik | Nur calc() |
Vollständige Arithmetik für alle Werte |
| Farben | Feste Werte | lighten, darken, mix und mehr |
Sass vs. SCSS Syntax
Sass unterstützt zwei Syntaxen:
SCSS (.scss) — die am weitesten verbreitete. Sie verwendet geschweifte Klammern und Semikolons, genau wie CSS. Jede gültige CSS-Datei ist automatisch auch eine gültige SCSS-Datei. Das macht den Einstieg nahtlos:
/* style.scss */
$primary: #3498db;
.button {
background: $primary;
color: white;
&:hover {
background: darken($primary, 10%);
}
}
Indented Syntax (.sass) — das Original. Sie nutzt Einrückungen und Zeilenumbrüche anstelle von Klammern und Semikolons, was sie prägnanter, aber weniger vertraut macht:
/* style.sass */
$primary: #3498db
.button
background: $primary
color: white
&:hover
background: darken($primary, 10%)
SCSS ist die Syntax, auf die du in praktisch jedem modernen Projekt stoßen wirst. Sofern du keinen spezifischen Grund hast, die indented Sass-Syntax zu wählen, nutze .scss.
Warum es Sass gibt
Sass wurde zum Industriestandard, weil es echte Probleme löst. Die Kernpunkte, die es adressiert:
Wiederholungen. Ohne Variablen bedeutet eine einzige Farbänderung eine „Suchen-und-Ersetzen“-Aktion über jede einzelne Datei hinweg. Sass-Variablen ermöglichen es, einen Wert einmal zu ändern und ihn überall zu aktualisieren.
Flache Struktur. Tief verschachtelte Komponenten führen zu langen, repetitiven Selektoren wie .card .card-header .card-title. Das Nesting in Sass spiegelt die HTML-Hierarchie direkt in deinen Styles wider.
Keine Wiederverwendbarkeit. CSS kennt kein Konzept von wiederverwendbaren Style-Blöcken. Eine Button-Komponente mit 10 Varianten bedeutet 10 nahezu identische Blöcke. Sass-Mixins und Extends eliminieren diese Duplizierung.
Fehlende Logik. Das Generieren einer Farbpalette, abwechselnde Zeilenfarben oder das Erstellen responsiver Breakpoints aus einer Liste erfordert normalerweise externe Tools. Sass bietet dir Schleifen und Bedingungen direkt im Stylesheet.
Organisation. Das Importieren von Dutzenden CSS-Dateien mit @import erzeugt einen flachen globalen Namensraum, in dem Namen unweigerlich kollidieren. Sass-Module (@use, @forward) lösen dies durch Namespacing.
Variablen
Variablen sind das einfachste und zugleich wirkungsvollste Feature von Sass. Eine Variable speichert einen Wert, den du in deinem gesamten Stylesheet wiederverwenden kannst:
/* style.scss */
$primary: #3498db;
$secondary: #2ecc71;
$font-stack: 'Helvetica Neue', Arial, sans-serif;
$spacing-unit: 8px;
body {
font-family: $font-stack;
}
.container {
padding: $spacing-unit * 3;
}
.btn-primary {
background: $primary;
color: white;
}
Ändere $primary einmal ganz oben, und jedes Element, das darauf referenziert, wird automatisch aktualisiert. Sass-Variablen sind Konstanten zur Kompilierzeit – sie existieren nicht im ausgegebenen CSS. Dies unterscheidet sie von CSS custom properties (--var), die zur Laufzeit im Browser existieren. Nutze Sass-Variablen für Werte, die sich nicht dynamisch ändern müssen.
Variablen haben einen Scope (Geltungsbereich). Eine Variable, die innerhalb einer Regel oder eines Mixins deklariert wird, ist lokal für diesen Block. Nutze !global, um eine globale Variable innerhalb eines lokalen Scopes zu überschreiben, obwohl dies nur selten notwendig ist:
/* style.scss */
$color: red; // global
.box {
$color: blue; // local — only exists inside .box
color: $color;
}
// $color is still red here
Nesting
Nesting ermöglicht es, Child-Selektoren innerhalb ihres Parents zu schreiben. Dies spiegelt die HTML-Struktur wider und hält zusammengehörige Styles gruppiert:
/* style.scss */
.nav {
display: flex;
gap: $spacing-unit * 2;
&__item {
padding: $spacing-unit;
&--active {
font-weight: bold;
border-bottom: 2px solid $primary;
}
&:hover {
background: rgba($primary, 0.1);
}
}
&__logo {
margin-right: auto;
}
}
Dies wird kompiliert zu:
/* compiled.css */
.nav { display: flex; gap: 16px; }
.nav__item { padding: 8px; }
.nav__item--active { font-weight: bold; border-bottom: 2px solid #3498db; }
.nav__item:hover { background: rgba(52, 152, 219, 0.1); }
.nav__logo { margin-right: auto; }
Der & Parent-Selektor ist essenziell. Er referenziert den Parent-Selektor, sodass &__item innerhalb von .nav zu .nav__item wird. Ohne & behandelt Sass das Ampersand als Parent-Kontext. Sie können & auch für Pseudo-Klassen und Pseudo-Elemente verwenden, anstatt diese als separate Blöcke zu nesten.
Obwohl natives CSS mittlerweile grundlegendes Nesting unterstützt, ist das Nesting in Sass ausgereifter – es unterstützt & für beliebige Parent-Referenzen, funktioniert überall und ist seit über einem Jahrzehnt praxiserprobt.
Partials und Imports
Partials sind Sass-Dateien, die dazu gedacht sind, importiert zu werden, anstatt einzeln kompiliert zu werden. Benennen Sie diese mit einem Unterstrich als Präfix — _variables.scss, _buttons.scss, _mixins.scss — und Sass wird sie bei der direkten Kompilierung überspringen:
// _variables.scss
$primary: #3498db;
$spacing: 8px;
$font-stack: 'Helvetica Neue', Arial, sans-serif;
// _buttons.scss
@use 'variables' as *;
.button {
padding: $spacing * 2;
background: $primary;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
// main.scss
@use 'variables' as *;
@use 'buttons';
@use 'layout';
@use 'typography';
Die @use-Regel importiert eine Datei als Modul. Sie greifen dann über einen Namespace auf deren Mitglieder zu oder verwenden as *, um alles in den Scope zu laden. Dies hält Ihren globalen Namespace sauber und verhindert Namenskollisionen zwischen Dateien.
Module: @use und @forward
Die @import-Regel ist veraltet. Sie hat alle Dateien in einem globalen Scope zusammengeführt, was bedeutete, dass eine $primary in einer Datei stillschweigend eine $primary in einer anderen überschreiben konnte. Die modernen Alternativen sind @use und @forward.
@use
@use importiert ein Modul und weist ihm einen Namespace zu:
/* style.scss */
@use 'variables';
.button {
background: variables.$primary;
padding: variables.$spacing * 2;
}
Sie können den Namespace per Alias anpassen oder alle Member in den Scope holen:
/* style.scss */
@use 'variables' as v;
@use 'variables' as *; // no namespace needed
@forward
@forward re-exportiert die Member eines Moduls, sodass Dateien, die das aktuelle Modul importieren, darauf zugreifen können. Dies wird verwendet, um sogenannte Barrel-Files zu erstellen – einen einzigen Einstiegspunkt, der mehrere Module exponiert:
// _index.scss
@forward 'variables';
@forward 'mixins';
@forward 'functions';
// main.scss
@use 'index' as *; // gets everything from variables, mixins and functions
Verwenden Sie @forward zusammen mit show und hide, um zu steuern, welche Member re-exportiert werden:
/* style.scss */
@forward 'variables' show $primary, $secondary;
@forward 'mixins' hide $internal-helper;
Mixins
Mixins sind wiederverwendbare Style-Blöcke, die du parametrisieren und an beliebiger Stelle einbinden kannst. Betrachte sie als Funktionen, die CSS-Deklarationen ausgeben:
/* mixins.scss */
@mixin flex-center {
display: flex;
justify-content: center;
align-items: center;
}
@mixin respond-to($breakpoint) {
@if $breakpoint == 'tablet' {
@media (min-width: 768px) { @content; }
} @else if $breakpoint == 'desktop' {
@media (min-width: 1024px) { @content; }
}
}
.hero {
@include flex-center;
min-height: 100vh;
@include respond-to('desktop') {
min-height: 80vh;
}
}
.card {
@include flex-center;
padding: 1rem;
}
Mixins können Standardparameter haben, eine beliebige Anzahl von Argumenten akzeptieren und @content verwenden, um einen Style-Block vom Aufrufer zu übernehmen. Sie sind der primäre Abstraktionsmechanismus in Sass – Design-Systeme, Responsive-Helper und Layer für die Browserkompatibilität basieren allesamt auf Mixins.
Funktionen
Sass-Funktionen berechnen und geben einen Wert zurück. Sie ähneln Mixins, aber anstatt CSS auszugeben, erzeugen sie einen Wert, den Sie zuweisen können:
/* functions.scss */
@function spacing($n) {
@return $n * 8px;
}
@function shade($color, $percentage) {
@return mix(black, $color, $percentage);
}
.hero {
padding: spacing(4); // 32px
background: shade(#3498db, 20%);
}
.sidebar {
padding: spacing(2); // 16px
}
Sass wird mit vielen integrierten Funktionen für Farben (lighten, darken, saturate, adjust-hue), Strings (str-length, str-insert), Mathematik (abs, min, max, round) und Listen (length, nth, append, index) ausgeliefert. Für projektspezifische Logik können Sie Ihre eigenen Funktionen schreiben.
Extends und Vererbung
Die @extend-Regel ermöglicht es einem Selektor, die Styles eines anderen zu übernehmen. Sass führt die beiden Selektoren im resultierenden CSS in einer einzigen Regel zusammen:
/* style.scss */
%message {
padding: 1rem;
border-radius: 4px;
margin-bottom: 1rem;
}
.success {
@extend %message;
background: #d4edda;
color: #155724;
}
.error {
@extend %message;
background: #f8d7da;
color: #721c24;
}
.warning {
@extend %message;
background: #fff3cd;
color: #856404;
}
Kompiliert zu:
/* compiled.css */
.success, .error, .warning {
padding: 1rem;
border-radius: 4px;
margin-bottom: 1rem;
}
.success { background: #d4edda; color: #155724; }
.error { background: #f8d7da; color: #721c24; }
.warning { background: #fff3cd; color: #856404; }
Placeholders (Selektoren, die mit % beginnen) werden nicht eigenständig in das CSS ausgegeben – sie erscheinen nur, wenn sie erweitert werden. Dies verhindert leere Regeln in deinem kompilierten Output.
Nutze @extend für gemeinsam genutzte strukturelle Muster. Für alles, was Parameter benötigt, verwende stattdessen ein Mixin – @extend kann keine Argumente entgegennehmen.
Operatoren
Sass unterstützt die Standard-Arithmetik-Operatoren für die Arbeit mit Zahlen:
/* style.scss */
$column-count: 12;
$gutter: 24px;
$gap: $gutter / 2; // 12px
$base: 16px;
$heading-1: $base * 2; // 32px
$heading-2: $base * 1.5; // 24px
$full-width: 100%;
$sidebar: $full-width / 3; // 33.333%
// Remainder
$remainder: 17 % 5; // 2
Sass unterstützt zudem String-Interpolation, Vergleichsoperatoren und boolesche Operatoren:
/* style.scss */
$primary: #3498db;
$dark: darken($primary, 20%);
$is-dark: true;
@mixin theme-bg {
@if $is-dark {
background: $dark;
} @else {
background: $primary;
}
}
Beachte, dass die Division (/) in einigen Kontexten (z. B. font: 16px/1.5) nun als CSS-Bruch behandelt wird. Um Mehrdeutigkeiten zu vermeiden, umschließe Divisionen mit math.div() oder verwende calc() für dynamische Divisionen.
Kontrollfluss
Sass enthält Bedingungsanweisungen und Schleifen, die CSS zur Kompilierzeit generieren:
@if / @else
/* style.scss */
$theme: 'light';
@mixin theme-bg {
@if $theme == 'light' {
background: white;
color: black;
} @else if $theme == 'dark' {
background: #1a1a2e;
color: white;
} @else {
background: #f0f0f0;
color: #333;
}
}
@each
Iteriert über eine Liste oder Map:
/* style.scss */
$colors: (
primary: #3498db,
secondary: #2ecc71,
danger: #e74c3c,
);
@each $name, $color in $colors {
.text-#{$name} {
color: $color;
}
.bg-#{$name} {
background: $color;
}
}
@for
Generiert einen Bereich von Selektoren:
/* style.scss */
@for $i from 1 through 12 {
.col-#{$i} {
width: ($i / 12) * 100%;
}
}
@for $i from 1 through 5 {
.mt-#{$i} {
margin-top: $i * 8px;
}
}
@while
Schleife, solange eine Bedingung wahr ist:
/* style.scss */
$columns: 12;
$i: $columns;
@while $i > 0 {
.col-#{$i} {
width: ($i / $columns) * 100%;
}
$i: $i - 1;
}
Maps und Listen
Sass bietet First-Class-Datenstrukturen für Kollektionen.
Listen sind geordnet und durch Kommas oder Leerzeichen getrennt:
/* style.scss */
$breakpoints: 480px, 768px, 1024px, 1280px;
@each $bp in $breakpoints {
@media (min-width: $bp) {
.container {
max-width: $bp;
}
}
}
// Lists can be nested
$margins: (8px, 16px, 24px, 32px);
Maps bestehen aus Key-Value-Paaren, ähnlich wie Objekte oder Dictionaries:
/* style.scss */
$theme: (
primary: #3498db,
secondary: #2ecc71,
bg: white,
text: #333,
);
@each $key, $value in $theme {
--color-#{$key}: #{$value};
}
Du kannst auf Map-Werte mit map-get zugreifen, sie mit map-merge zusammenführen, die Existenz mit map-has-key prüfen und sie mit @each iterieren.
Sass Built-in Functions
Sass wird mit einer umfangreichen Standardbibliothek ausgeliefert:
/* style.scss */
// Colour manipulation
$primary: #3498db;
.lighter { color: lighten($primary, 20%); }
.darker { color: darken($primary, 15%); }
.desaturated { color: desaturate($primary, 30%); }
.hue-shifted { color: adjust-hue($primary, 30deg); }
// Colour functions
$alpha: rgba($primary, 0.5); // semi-transparent
$contrast: contrast-color($primary); // contrast-safe colour
// Maths
$rounded: round(3.14); // 3
$limited: clamp(1, 10, 5); // 5
$half: math.div(100%, 2); // 50%
// Strings
$name: to-upper-case('sass'); // SASS
$length: str-length('hello'); // 5
$joined: str-insert('hello', ' world', 6); // 'hello world'
// Lists
$items: append(1px, 2px, 3px, 4px);
$first: nth($items, 1); // 1px
$count: length($items); // 4
Diese Funktionen sind in SCSS global verfügbar sowie über @use 'sass:color', @use 'sass:math', @use 'sass:string', @use 'sass:list' und @use 'sass:map' zugänglich.
So verwendest du Sass
Dart Sass
Dart Sass ist die kanonische und einzige aktiv gewartete Sass-Implementierung. Installiere sie mit:
npm install sass
Kompiliere anschließend Dateien direkt:
npx sass src/styles.scss dist/styles.css
Integration in Build-Tools
In den meisten modernen Projekten wird Sass über deinen Bundler gesteuert. Vite, webpack, Parcel und esbuild unterstützen Sass out-of-the-box:
Vite — installiere einfach sass und importiere .scss-Dateien:
import './styles.scss';
webpack — füge sass-loader hinzu:
module.exports = {
module: { rules: [{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }] }
};
CLI-Kompilierung
# Watch mode — recompile on every save
npx sass --watch src:dist
# One compile
npx sass src/styles.scss dist/styles.css
# Output compressed CSS
npx sass --style=compressed src/styles.scss dist/styles.css
Best Practices
- Nutze die SCSS-Syntax. Sie ist CSS-kompatibel, weit verbreitet und wesentlich besser lesbar als die eingerückte Syntax.
- Nutze
@useund@forward, niemals@import. Das Import-System ist veraltet und führt zu einer Verschmutzung des globalen Scopes. - Organisiere dich mit Partials. Ein Anliegen pro Datei:
_variables.scss,_mixins.scss,_buttons.scss,_layout.scss. - Nutze Namespaces für deine Module. Verwende
@use 'module' as varoder lass den Standard-Namespace (module.$var) verdeutlichen, woher die Werte kommen. - Nutze Placeholders für gemeinsame Muster.
%placeholder-Selektoren erzeugen nur dann CSS, wenn sie erweitert werden, was den Output schlank hält. - Schreibe parametrisierte Mixins statt Extends. Mixins sind flexibler und erzeugen explizites, vorhersagbares CSS.
- Halte Business-Logik aus den Stylesheets fern. Sass-Funktionen und Schleifen gehören in deine Build-Pipeline, nicht in deine Komponenten-Logik.
- Nutze Linting für dein Sass. Verwende
stylelintmit einem Sass-Plugin, um veraltete Funktionen zu finden und Konventionen durchzusetzen. - Gib für die Produktion komprimiertes CSS aus. Nutze
--style=compressedoder lass deinen Bundler die Minifizierung übernehmen. - Vermeide tief verschachtelte Selektoren. Zwei bis drei Ebenen sind ausreichend. Eine tiefere Verschachtelung deutet meist auf ein Problem bei der Benennung oder Struktur hin.