Overerving in SASS
Dit artikel legt overerving in SASS uit.
We leggen overerving in SASS uit met praktische voorbeelden.
YouTube Video
Overerving in SASS
Overerving in SASS (@extend) is een mechanisme waarmee je de stijlen van de ene selector op een andere kunt toepassen zonder duplicatie. Omdat dezelfde stijlen worden 'gecombineerd' en toegepast op meerdere elementen in de markup, is de gegenereerde CSS minder snel overbodig; echter, bij verkeerd gebruik kunnen ongewenste samenvoegingen van selectors optreden.
Basis: Hoe gebruik je @extend
Hieronder volgt een eenvoudig voorbeeld waarbij .btn--primary de stijlen van .btn overneemt. @extend is een directive die de doelselector uitbreidt.
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}- Met
@extenderft.btn--primaryde basisstijlen van.btnen overschrijft alleen de noodzakelijke onderdelen.
Gegenereerde 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: Gebruik van placeholders (%placeholder)
Placeholder-selectors (%name) zijn selectors die niet worden omgezet naar CSS. Ze worden veel gebruikt, vooral wanneer je algemene stijlen veilig wilt delen voor uitsluitend overerving tussen meerdere componenten.
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}.carden.panelerven beide van%card-base, waardoor ze gemeenschappelijke stijlen delen en verschillen kunnen toevoegen waar nodig.
Gegenereerde 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}Meervoudige overerving (meerdere @extend)
Het is mogelijk om meerdere placeholders of klassen tegelijk te erven. Hoewel de herbruikbaarheid van stijlen wordt verbeterd, is het belangrijk om bij te houden welke regels met welke selectors worden gecombineerd.
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}- Dit is een voorbeeld waarin een knop twee placeholders erft: één voor 'basis' en één voor 'grootte'.
.btn--lgerft zowel%btn-baseals%btn-large, waardoor de basisopmaak wordt gecombineerd met grotere afmetingen.
Gegenereerde 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 gedrag (samenvoegingsmechanisme) en waarschuwingen voor 'selector-explosie'
@extend zorgt ervoor dat alle overeenkomende selectors worden samengevoegd, wat soms ongewenste combinaties van selectors tot gevolg kan hebben.
Het volgende voorbeeld laat zien hoe de output kan toenemen wanneer dezelfde basisklasse op meerdere plaatsen wordt uitgebreid.
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}- Wanneer meerdere componenten
.utilityerven, worden selectors samengevoegd, wat in grootschalige projecten kan leiden tot opzwelling van de CSS.
Gegenereerde 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 en .class versus element-selectors (tags) — prioriteit en bijwerkingen
@extend kan niet alleen op klassen, maar ook op element-selectors worden toegepast. Het uitbreiden van elementen vergroot echter het toepassingsgebied, waardoor het risico toeneemt dat regels onbedoeld op onverwachte plekken worden toegepast.
Hieronder volgt een voorbeeld van het uitbreiden van een elementselector en het eventuele effect daarvan.
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 dit voorbeeld zorgt het overerven van de elementselector
h1ervoor dat.titlewordt samengevoegd met dezelfde stijlen alsh1. - Hoewel het in kleinschalige gevallen handig lijkt, kunnen naarmate je project groeit de regels voor
h1zich onverwacht combineren met.title, waardoor stijlen complexer en minder onderhoudbaar worden. Daarom is het ontwerpen van stijlen vooral rond klassen en placeholders gemakkelijker te onderhouden.
Gegenereerde CSS
1h1,
2.title {
3 font-size: 2rem;
4 margin-bottom: 0.5rem;
5}
6
7.title {
8 color: #333;
9}Toepassingen van @extend en !optional
Als je !optional gebruikt met @extend, kun je fouten onderdrukken wanneer het overervingsdoel niet bestaat. Dit is vooral handig in code die als bibliotheek fungeert of in gevallen waarin placeholders conditioneel worden gedefinieerd.
Hieronder volgt een voorbeeld van het veilig proberen te erven van een klasse die mogelijk niet bestaat, met behulp van !optional.
1/* Try to extend a class that might not exist */
2.component {
3 @extend .maybe-existing !optional;
4 padding: 1rem;
5}- Als
.maybe-existingniet bestaat, gebeurt er niets en wordt het overgeslagen. Dit kun je gebruiken als je een extensie veilig wilt proberen.
Gegenereerde CSS
1.component {
2 padding: 1rem;
3}Vergelijking van @extend en mixins (@mixin / @include)
@extend en @mixin kunnen overlappende doelen hebben, maar hun output en gebruik verschillen.
-
@extend- De gegenereerde CSS voorkomt overbodigheid door selectors samen te voegen.
- Omdat selectors na het genereren worden samengevoegd, kunnen onbedoelde combinaties ontstaan.
- Parameters kunnen niet worden doorgegeven (al kan dit deels worden ondervangen door placeholders te combineren).
-
@mixin/@include- Elke oproep dupliceert de stijlen (wat zorgt voor overbodige output).
- Je kunt parameters doorgeven en logica toevoegen zoals voorwaarden of loops.
- De output is voorspelbaarder, maar het bestand wordt groter.
Hieronder volgt een vergelijking met zowel @mixin als @extend om dezelfde knopstijlen te realiseren.
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}@mixinlaat je flexibel stijlen invoegen, terwijl@extendde output efficiënt samenvoegt; je kunt ze dus afhankelijk van de situatie toepassen.
Gegenereerde CSS
Output van @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 van @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 richtlijnen
SASS-overerving is een krachtige functie om de herbruikbaarheid van stijlen te vergroten. Onjuist gebruik kan echter het samenvoegen van stijlen ingewikkeld maken en het onderhoud verminderen. Hieronder volgen enkele belangrijke punten om overerving veilig en efficiënt te gebruiken.
- Gebruik placeholders voor puur gemeenschappelijke componentstijlen, zoals structuur en lay-out. Bovendien kun je
@mixingebruiken als dynamische parameterisatie vereist is. - Je moet het direct overerven van HTML-elementen zoals
h1vermijden. Onbedoelde selectorcombinaties kunnen optreden, waardoor onverwachte CSS wordt gegenereerd. - Het gebruik van naamconventies zoals BEM of duidelijke voorvoegsels om aan te geven waar elke placeholder voor dient, helpt om alles veilig te houden.
- Het is veiliger om
@extendbinnen hetzelfde bestand te gebruiken. Vooral in grote projecten is het aan te raden overerving binnen de reikwijdte van elk component te ontwerpen, zodat het eenvoudiger wordt om overervingsrelaties bij te houden.
Samenvatting
De @extend-functie in SASS is een handige manier om gemeenschappelijke stijlen efficiënt te hergebruiken en ontwerpconsistentie te waarborgen. Omdat selectorcombinaties echter snel complex kunnen worden, is het noodzakelijk om deze functie voorzichtig en binnen beperkte reikwijdte te gebruiken. Door gedeelde stijlen te groeperen met placeholder selectors (%placeholder) en @mixin te gebruiken voor onderdelen die dynamische parameters vereisen, kun je een eenvoudig en goed onderhoudbaar ontwerp behouden.
Je kunt het bovenstaande artikel volgen met Visual Studio Code op ons YouTube-kanaal. Bekijk ook het YouTube-kanaal.