Vererbung in SASS

Dieser Artikel erklärt die Vererbung in SASS.

Wir erklären die Vererbung in SASS anhand von praktischen Beispielen.

YouTube Video

Vererbung in SASS

Die Vererbung in SASS (@extend) ist ein Mechanismus, mit dem Sie die Styles eines Selektors auf einen anderen ohne Duplizierung anwenden können. Die gleichen Styles werden für mehrere Elemente im Markup 'kombiniert' und ausgegeben, sodass das resultierende CSS weniger redundant ist; jedoch kann bei unsachgemäßer Verwendung zu unbeabsichtigten Selektorkombinationen führen.

Grundlagen: Wie man @extend verwendet

Unten sehen Sie ein einfaches Beispiel, bei dem .btn--primary die Styles von .btn erbt. @extend ist eine Direktive, die den Zielselektor erweitert.

 1// Base button styles
 2.btn {
 3  padding: 0.5rem 1rem;
 4  border-radius: 4px;
 5  border: 1px solid #ccc;
 6  background: white;
 7  color: #333;
 8}
 9
10/* Primary button extends the base .btn */
11.btn--primary {
12  @extend .btn;
13  background: #007bff;
14  color: white;
15}
  • Durch die Verwendung von @extend erbt .btn--primary die Basis-Styles von .btn und überschreibt nur die notwendigen Teile.

Erzeugtes CSS

 1.btn, .btn--primary {
 2  padding: 0.5rem 1rem;
 3  border-radius: 4px;
 4  border: 1px solid #ccc;
 5  background: white;
 6  color: #333;
 7}
 8
 9.btn--primary {
10  background: #007bff;
11  color: white;
12}

Best Practice: Verwenden von Platzhaltern (%placeholder)

Platzhalter-Selektoren (%name) sind Selektoren, die nicht im CSS ausgegeben werden. Sie werden häufig verwendet, insbesondere wenn Sie gemeinsame Styles sicher ausschließlich für die Vererbung über mehrere Komponenten hinweg teilen möchten.

 1// %placeholder will not be output directly
 2%card-base {
 3  padding: 1rem;
 4  border-radius: 6px;
 5  box-shadow: 0 1px 3px rgba(0,0,0,0.08);
 6  background: #fff;
 7}
 8
 9/* Components extend the placeholder */
10.card {
11  @extend %card-base;
12  border: 1px solid #eee;
13}
14
15.panel {
16  @extend %card-base;
17  border: 1px solid #ddd;
18}
  • .card und .panel erben beide von %card-base, sodass sie gemeinsame Styles teilen und nach Bedarf Unterschiede hinzufügen können.

Erzeugtes CSS

 1.card, .panel {
 2  padding: 1rem;
 3  border-radius: 6px;
 4  box-shadow: 0 1px 3px rgba(0,0,0,0.08);
 5  background: #fff;
 6}
 7
 8.card {
 9  border: 1px solid #eee;
10}
11
12.panel {
13  border: 1px solid #ddd;
14}

Mehrfache Vererbung (Mehrfaches @extend)

Es können mehrere Platzhalter oder Klassen gleichzeitig geerbt werden. Obwohl die Wiederverwendbarkeit von Styles verbessert wird, ist es wichtig, den Überblick zu behalten, welche Regeln mit welchen Selektoren kombiniert werden.

 1%btn-base {
 2  display: inline-block;
 3  padding: 0.5rem 1rem;
 4  border-radius: 3px;
 5}
 6
 7%btn-large {
 8  padding: 0.75rem 1.5rem;
 9  font-size: 1.125rem;
10}
11
12/* Composite button that extends both placeholders */
13.btn--lg {
14  @extend %btn-base;
15  @extend %btn-large;
16  background: #222;
17  color: #fff;
18}
  • Dies ist ein Beispiel, bei dem ein Button zwei Platzhalter erbt: einen für die 'Basis' und einen für die 'Größe'.
  • .btn--lg erbt sowohl %btn-base als auch %btn-large und kombiniert das Basis-Layout mit einer größeren Größe.

Erzeugtes CSS

1.btn--lg {
2  display: inline-block;
3  /* %btn-large overrides the padding from %btn-base */
4  padding: 0.75rem 1.5rem;
5  border-radius: 3px;
6  font-size: 1.125rem;
7  background: #222;
8  color: #fff;
9}

@extend-Verhalten (Zusammenführungsmechanismus) und Hinweise zur 'Selektor-Explosion'

@extend gibt alle passenden Selektoren zusammengeführt aus, was gelegentlich zu unbeabsichtigten Selektorkombinationen führen kann.

Das folgende Beispiel zeigt, wie die Ausgabe ansteigt, wenn dieselbe Basisklasse an mehreren Stellen erweitert wird.

 1/* Many components extend .utility */
 2/* A generic utility class */
 3.utility {
 4  margin-bottom: 1rem;
 5}
 6
 7/* Nested selectors that extend .utility */
 8.header {
 9  @extend .utility;
10  .title {
11    font-weight: bold;
12  }
13}
14
15.footer {
16  @extend .utility;
17  .note {
18    color: #888;
19  }
20}
21
22.article {
23  @extend .utility;
24  .content {
25    line-height: 1.6;
26  }
27}
28
29.sidebar {
30  @extend .utility;
31  .section {
32    padding: 1rem;
33  }
34}
  • Wenn mehrere Komponenten .utility erben, werden die Selektoren zusammengeführt – in großen Projekten kann dies zu aufgeblähtem CSS führen.

Erzeugtes CSS

 1.utility,
 2.header,
 3.footer,
 4.article,
 5.sidebar {
 6  margin-bottom: 1rem;
 7}
 8
 9.header .title {
10  font-weight: bold;
11}
12
13.footer .note {
14  color: #888;
15}
16
17.article .content {
18  line-height: 1.6;
19}
20
21.sidebar .section {
22  padding: 1rem;
23}

@extend sowie .class vs. Element-Selektoren (Tags) — Priorität und Nebeneffekte

@extend kann nicht nur auf Klassen, sondern auch auf Elementselektoren angewendet werden. Allerdings vergrößert das Erweitern von Elementen den betroffenen Geltungsbereich und erhöht das Risiko, dass Regeln unbeabsichtigt an unerwünschten Stellen angewendet werden.

Unten finden Sie ein Beispiel für das Erweitern eines Element-Selektors und die Auswirkungen davon.

 1/* Extending an element selector (not recommended) */
 2h1 {
 3  font-size: 2rem;
 4  margin-bottom: 0.5rem;
 5}
 6
 7/* If you extend h1, the resulting selector will include your class with h1 */
 8.title {
 9  @extend h1;
10  color: #333;
11}
12
13/* Output becomes:
14h1, .title { font-size: 2rem; margin-bottom: 0.5rem; }
15*/
  • In diesem Beispiel führt das Erben des Element-Selektors h1 dazu, dass .title mit denselben Styles wie h1 zusammengeführt wird.
  • Auch wenn es in kleinen Anwendungsfällen praktisch erscheinen mag, könnten mit wachsendem Projekt Regeln für h1 unerwartet mit .title kombiniert werden, was die Styles komplexer macht und die Wartbarkeit verringert. Daher ist es einfacher, die Styles wartbar zu halten, wenn man sie hauptsächlich um Klassen und Platzhalter herum gestaltet.

Erzeugtes CSS

1h1,
2.title {
3  font-size: 2rem;
4  margin-bottom: 0.5rem;
5}
6
7.title {
8  color: #333;
9}

Anwendungsfälle für @extend und !optional

Wenn Sie !optional mit @extend angeben, können Sie Fehler unterdrücken, wenn das Vererbungsziel nicht existiert. Dies ist besonders nützlich in bibliotheksähnlichem Code oder in Fällen, in denen Platzhalter nur unter bestimmten Bedingungen definiert werden.

Das folgende Beispiel zeigt, wie man mit !optional versucht, sicher eine möglicherweise nicht existierende Klasse zu erben.

1/* Try to extend a class that might not exist */
2.component {
3  @extend .maybe-existing !optional;
4  padding: 1rem;
5}
  • Falls .maybe-existing nicht existiert, geschieht nichts und die Anweisung wird übersprungen. Dies kann verwendet werden, wenn Sie eine Erweiterung sicher versuchen möchten.

Erzeugtes CSS

1.component {
2  padding: 1rem;
3}

Vergleich von @extend und Mixins (@mixin / @include)

@extend und @mixin haben manchmal ähnliche Zwecke, aber ihre Ausgaben und Anwendungsfälle unterscheiden sich.

  • @extend

    • Das generierte CSS reduziert Redundanz durch Zusammenführen von Selektoren.
    • Da Selektoren nach der Generierung zusammengeführt werden, können unbeabsichtigte Kombinationen entstehen.
    • Parameter können nicht übergeben werden (dies kann aber durch die Kombination von Platzhaltern ausgeglichen werden).
  • @mixin / @include

    • Jeder Aufruf dupliziert die Styles (führt zu redundanter Ausgabe).
    • Sie können Parameter übergeben und Logik wie Bedingungen oder Schleifen einfügen.
    • Die Ausgabe ist vorhersagbarer, aber die Dateigröße steigt an.

Unten finden Sie einen Vergleich, bei dem sowohl @mixin als auch @extend zur Implementierung der gleichen Button-Stile verwendet werden.

 1/* Mixin approach */
 2@mixin btn-styles($bg, $color) {
 3  display: inline-block;
 4  padding: 0.5rem 1rem;
 5  background: $bg;
 6  color: $color;
 7  border-radius: 4px;
 8}
 9
10/* Use mixin */
11.btn {
12  @include btn-styles(white, #333);
13}
14
15.btn--primary {
16  @include btn-styles(#007bff, white);
17}
18
19/* Extend approach (shared placeholder) */
20%btn-base {
21  display: inline-block;
22  padding: 0.5rem 1rem;
23  border-radius: 4px;
24}
25
26.btn2 {
27  @extend %btn-base;
28  background: white;
29  color: #333;
30}
31
32.btn2--primary {
33  @extend %btn-base;
34  background: #007bff;
35  color: white;
36}
  • @mixin erlaubt es Ihnen, Styles flexibel einzufügen, während @extend die Ausgabe effizient zusammenfasst – je nach Anwendungsfall kann die jeweils passende Methode gewählt werden.

Erzeugtes CSS

Ausgabe von @mixin
 1.btn {
 2  display: inline-block;
 3  padding: 0.5rem 1rem;
 4  background: white;
 5  color: #333;
 6  border-radius: 4px;
 7}
 8
 9.btn--primary {
10  display: inline-block;
11  padding: 0.5rem 1rem;
12  background: #007bff;
13  color: white;
14  border-radius: 4px;
15}
Ausgabe von @extend
 1.btn2,
 2.btn2--primary {
 3  display: inline-block;
 4  padding: 0.5rem 1rem;
 5  border-radius: 4px;
 6}
 7
 8.btn2 {
 9  background: white;
10  color: #333;
11}
12
13.btn2--primary {
14  background: #007bff;
15  color: white;
16}

Praktische Richtlinien

Die Vererbung in SASS ist eine leistungsstarke Funktion zur Steigerung der Wiederverwendbarkeit von Styles. Falsche Nutzung kann jedoch das Zusammenführen von Styles verkomplizieren und die Wartbarkeit verschlechtern. Im Folgenden sind einige wichtige Punkte aufgeführt, um Vererbung sicher und effizient zu nutzen.

  • Verwenden Sie Platzhalter für rein gemeinsame Komponenten-Styles wie Struktur und Layout. Zusätzlich können Sie @mixin verwenden, wenn eine dynamische Parametrierung erforderlich ist.
  • Sie sollten es vermeiden, direkt von HTML-Elementen wie h1 zu erben. Es können unbeabsichtigte Selektorkombinationen auftreten, was zur Generierung von unerwartetem CSS führen kann.
  • Die Verwendung von Namenskonventionen wie BEM oder eindeutigen Präfixen, die den Zweck jedes Platzhalters zeigen, erhöht die Sicherheit.
  • Es ist sicherer, @extend innerhalb derselben Datei zu verwenden. Gerade in großen Projekten empfiehlt es sich, die Vererbung im Rahmen jeder Komponente zu gestalten, um die Nachverfolgung der Vererbungsbeziehungen zu erleichtern.

Zusammenfassung

Die @extend-Funktion in SASS ist eine bequeme Möglichkeit, gemeinsame Styles effizient wiederzuverwenden und ein konsistentes Design sicherzustellen. Da Selektorkombinationen jedoch schnell komplex werden können, sollte diese Funktion mit Bedacht und in begrenztem Umfang eingesetzt werden. Indem Sie gemeinsame Styles mit Platzhalter-Selektoren (%placeholder) gruppieren und @mixin für Teile verwenden, die dynamische Parameter benötigen, können Sie ein einfaches und leicht wartbares Design beibehalten.

Sie können den obigen Artikel mit Visual Studio Code auf unserem YouTube-Kanal verfolgen. Bitte schauen Sie sich auch den YouTube-Kanal an.

YouTube Video