Arv i SASS

Denne artikkelen forklarer arv i SASS.

Vi skal forklare arv i SASS med praktiske eksempler.

YouTube Video

Arv i SASS

Arv i SASS (@extend) er en mekanisme som lar deg bruke stilene fra én selektor på en annen uten duplisering. Siden de samme stilene blir 'kombinert' og utgitt for flere elementer i markupen, blir den resulterende CSSen mindre redundant; men hvis det brukes feil, kan det føre til utilsiktede sammenslåinger av selektorer.

Grunnleggende: Hvordan bruke @extend

Nedenfor er et grunnleggende eksempel hvor .btn--primary arver stilene til .btn. @extend er en direktiv som utvider målselektoren.

 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}
  • Ved å bruke @extend, arver .btn--primary grunnstilene til .btn og overstyrer kun de nødvendige delene.

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

Beste praksis: Bruke plassholdere (%placeholder)

Plassholder-selektorer (%name) er selektorer som ikke blir skrevet ut til CSS. De brukes mye, spesielt når du trygt vil dele felles stiler utelukkende for arv på tvers av flere 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 og .panel arver fra %card-base, slik at de kan dele felles stiler og legge til forskjeller etter behov.

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

Multippel arv (flere @extend)

Du kan arve flere plassholdere eller klasser samtidig. Selv om gjenbruk av stiler forbedres, er det viktig å holde oversikt over hvilke regler som kombineres med hvilke selektorer.

 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}
  • Dette er et eksempel der en knapp arver to plassholdere, én for 'base' og én for 'størrelse'.
  • .btn--lg arver både %btn-base og %btn-large, og kombinerer grunnoppsettet med større størrelse.

Generert 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-atferd (sammenslåingsmekanisme) og advarsler om 'selektoreksplosjon'

@extend kombinerer alle matchende selektorer sammen, noe som noen ganger kan føre til utilsiktede kombinasjoner av selektorer.

Følgende eksempel viser hvordan utdataene kan øke når samme baseklasse utvides på flere steder.

 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 flere komponenter arver .utility, slås selektorene sammen og, i store prosjekter, kan dette føre til at CSSen blir for stor.

Generert 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 og .class vs elementselektorer (tagger) — prioritet og bivirkninger

@extend kan brukes ikke bare på klasser, men også på element-selektorer. Men å utvide elementer øker omfanget som påvirkes, noe som øker risikoen for at regler utilsiktet brukes på uventede steder.

Nedenfor er et eksempel på å utvide en elementselektor og hvilken 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 dette eksemplet gjør arv av elementselektoren h1 at .title slås sammen med de samme stilene som h1.
  • Selv om det kan virke praktisk i småskala, kan reglene for h1 uventet kombineres med .title når prosjektet ditt vokser, noe som gjør stilene mer komplekse og vedlikeholdbarheten dårligere. Derfor gjør det stiler enklere å vedlikeholde hvis de hovedsakelig utformes rundt klasser og plassholdere.

Generert CSS

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

Bruksområder for @extend og !optional

Hvis du angir !optional med @extend, kan du undertrykke feil når arvmålet ikke eksisterer. Dette er spesielt nyttig i biblioteklignende kode eller der plassholdere er betinget definert.

Følgende er et eksempel på å prøve å arve en klasse som kanskje ikke eksisterer ved å bruke !optional.

1/* Try to extend a class that might not exist */
2.component {
3  @extend .maybe-existing !optional;
4  padding: 1rem;
5}
  • Hvis .maybe-existing ikke finnes, skjer ingenting og det blir hoppet over. Du kan bruke dette når du ønsker å gjøre en utvidelse trygt.

Generert CSS

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

Sammenligning av @extend og mixins (@mixin / @include)

@extend og @mixin har noen ganger overlappende formål, men outputen og bruksområdene deres er forskjellige.

  • @extend

    • Den genererte CSSen reduserer redundans ved å slå sammen selektorer.
    • Siden selektorer slås sammen etter generering, kan utilsiktede kombinasjoner forekomme.
    • Parametre kan ikke sendes (men dette kan kompenseres ved å kombinere plassholdere).
  • @mixin / @include

    • Hver kall dupliserer stilene (førende til redundant output).
    • Du kan sende parametre og inkludere logikk som betingelser eller løkker.
    • Outputen er mer forutsigbar, men filstørrelsen øker.

Nedenfor er en sammenligning der både @mixin og @extend brukes for å implementere de samme knappestilene.

 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 lar deg fleksibelt sette inn stiler, mens @extend konsoliderer outputen effektivt, så du kan bruke hver etter hensikten og bruksområdet.

Generert CSS

Output fra @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}
Output fra @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}

Praktiske retningslinjer

Arv i SASS er en kraftig funksjon for å øke gjenbruk av stiler. Feil bruk kan imidlertid gjøre sammenslåing av stiler komplisert og redusere vedlikeholdbarheten. Nedenfor er noen viktige punkter for å bruke arv trygt og effektivt.

  • Bruk plassholdere for rene felles komponentstiler, som struktur og layout. I tillegg, hvis dynamiske parametere er nødvendig, kan du bruke @mixin.
  • Du bør unngå å arve HTML-elementer som h1 direkte. Utilsiktede selektorkombinasjoner kan oppstå, noe som kan føre til at uventet CSS genereres.
  • Å bruke navngivningskonvensjoner som BEM eller tydelige prefikser for å vise hva hver plassholder brukes til, bidrar til økt sikkerhet.
  • Det er tryggere å bruke @extend innenfor samme fil. Spesielt i store prosjekter er det lurt å designe arv innenfor hver enkelt komponents omfang for å enklere holde oversikt over arverelasjoner.

Sammendrag

@extend-funksjonen i SASS er en praktisk måte å effektivt gjenbruke felles stiler og sikre designkonsistens. Men fordi selektorkombinasjoner lett kan bli komplekse, er det nødvendig å bruke denne funksjonen nøye og i begrenset omfang. Ved å gruppere delte stiler med plassholder-selektorer (%placeholder) og bruke @mixin for deler som krever dynamiske parametere, kan du opprettholde et enkelt og lett vedlikeholdbart design.

Du kan følge med på artikkelen ovenfor ved å bruke Visual Studio Code på vår YouTube-kanal. Vennligst sjekk ut YouTube-kanalen.

YouTube Video