Arv i SASS

Den här artikeln förklarar arv i SASS.

Vi kommer att förklara arv i SASS med praktiska exempel.

YouTube Video

Arv i SASS

Arv i SASS (@extend) är en mekanism som låter dig tillämpa stilarna från en selektor på en annan utan duplicering. Eftersom samma stilar 'kombineras' och används för flera element i markupen, blir den resulterande CSS-filen mindre redundant; men om det används felaktigt kan det leda till oavsiktliga sammanslagningar av selektorer.

Grunder: Hur man använder @extend

Nedan finns ett grundläggande exempel där .btn--primary ärver stilarna från .btn. @extend är en direktiv som utökar målselektorn.

 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}
  • Genom att använda @extend ärver .btn--primary baskodens stilar från .btn och skriver endast över nödvändiga delar.

Genererad 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}

Bästa praxis: Använda platshållare (%placeholder)

Platshållarväljare (%name) är väljare som inte tas med i CSS-utdata. De används ofta, särskilt när du vill dela gemensamma stilar säkert och exklusivt för arv mellan flera komponenter.

 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}
  • Både .card och .panel ärver från %card-base, vilket gör att de kan dela gemensamma stilar men lägga till skillnader vid behov.

Genererad 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}

Multipelt arv (Flera @extend)

Du kan ärva flera platshållare eller klasser samtidigt. Även om återanvändningen av stilar förbättras, är det viktigt att hålla koll på vilka regler som kombineras med vilka väljare.

 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}
  • Det här är ett exempel där en knapp ärver två platshållare, en för 'bas' och en för 'storlek'.
  • .btn--lg ärver både %btn-base och %btn-large och kombinerar grundlayouten med större storlek.

Genererad 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-beteende (sammanfogningsmekanism) och varningar om 'selektorexplosion'

@extend skriver ut alla matchande selektorer sammanslagna, vilket ibland kan resultera i oavsiktliga kombinationer av selektorer.

Följande exempel visar hur antalet utskrifter kan öka när samma basklass ärvs på flera ställen.

 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}
  • När flera komponenter ärver .utility slås selektorerna samman, vilket i stora projekt kan orsaka uppsvälld CSS.

Genererad 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 och .klass vs elementselektorer (taggar) – prioritet och bieffekter

@extend kan användas inte bara på klasser utan även på elementväljare. Att utöka element ökar dock det påverkade omfånget, vilket ökar risken för att regler tillämpas oavsiktligt på fel ställen.

Nedan finns ett exempel på att utöka en elementselektor och den effekt det kan ha.

 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*/
  • I detta exempel leder arv av elementselektorn h1 till att .title får samma stilar som h1.
  • Även om det kan verka bekvämt i mindre projekt, kan regler för h1 oväntat kombineras med .title när projektet växer, vilket gör stilarna mer komplexa och svårare att underhålla. Därför är det enklare att underhålla stilar när de främst utformas kring klasser och platshållare.

Genererad CSS

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

Användningsfall för @extend och !optional

Om du anger !optional med @extend kan du undertrycka fel när arvmålet inte finns. Detta är särskilt användbart i kod som liknar bibliotek eller i fall där platshållare definieras villkorligt.

Nedan är ett exempel på att säkert försöka ärva en klass som kanske inte finns, med hjälp av !optional.

1/* Try to extend a class that might not exist */
2.component {
3  @extend .maybe-existing !optional;
4  padding: 1rem;
5}
  • Om .maybe-existing inte finns händer ingenting och det hoppas över. Du kan använda detta när du vill försöka utöka på ett säkert sätt.

Genererad CSS

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

Jämförelse mellan @extend och mixins (@mixin / @include)

@extend och @mixin har ibland överlappande syften, men deras utskrifter och användningsområden skiljer sig åt.

  • @extend

    • Den genererade CSS-filen minskar redundans genom att sammanfoga selektorer.
    • Eftersom selektorer slås ihop efter genereringen kan oavsiktliga kombinationer uppstå.
    • Parametrar kan inte skickas (även om detta kan kompenseras genom att kombinera platshållare).
  • @mixin / @include

    • Varje anrop duplicerar stilarna (vilket orsakar onödig utskrift).
    • Du kan skicka in parametrar och inkludera logik som villkor eller loopar.
    • Utskriften är mer förutsägbar, men filstorleken ökar.

Nedan finns en jämförelse där både @mixin och @extend används för att implementera samma knappstilar.

 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 låter dig flexibelt lägga in stilar, medan @extend effektivt slår samman utskriften, så du kan använda respektive funktion beroende på situation.

Genererad CSS

Utskrift från @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}
Utskrift från @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}

Praktiska riktlinjer

Arv i SASS är en kraftfull funktion för att öka återanvändbarheten av stilar. Felaktig användning kan dock göra stil-sammanslagning komplex och minska underhållsmöjligheten. Nedan följer några viktiga punkter för att använda arv på ett säkert och effektivt sätt.

  • Använd platshållare för rent gemensamma komponentstilar, som struktur och layout. Om dynamiska parametrar behövs kan du dessutom använda @mixin.
  • Du bör undvika att direkt ärva HTML-element som h1. Oavsiktliga kombinationer av väljare kan uppstå, vilket kan leda till att oväntad CSS genereras.
  • Använd namnkonventioner som BEM eller tydliga prefix för att visa vad varje platshållare är till för; det hjälper till att hålla saker säkra.
  • Det är säkrare att använda @extend inom samma fil. Särskilt i stora projekt är det rekommenderat att utforma arv inom varje komponents omfång för att enkelt kunna följa arvrelationerna.

Sammanfattning

Funktionen @extend i SASS är ett smidigt sätt att effektivt återanvända gemensamma stilar och säkerställa designkonsekvens. Eftersom kombinationer av väljare lätt kan bli komplexa är det dock nödvändigt att använda denna funktion försiktigt och inom begränsat omfång. Genom att gruppera gemensamma stilar med platshållarväljare (%placeholder) och använda @mixin för delar som kräver dynamiska parametrar kan du behålla en enkel och lättskött design.

Du kan följa med i artikeln ovan med hjälp av Visual Studio Code på vår YouTube-kanal. Vänligen kolla även in YouTube-kanalen.

YouTube Video