Héritage dans SASS
Cet article explique l'héritage dans SASS.
Nous expliquerons l'héritage dans SASS avec des exemples pratiques.
YouTube Video
Héritage dans SASS
L'héritage dans SASS (@extend) est un mécanisme qui vous permet d'appliquer les styles d'un sélecteur à un autre sans duplication. Comme les mêmes styles sont « combinés » et générés pour plusieurs éléments du balisage, le CSS produit est moins susceptible d'être redondant ; cependant, en cas de mauvaise utilisation, cela peut conduire à des fusions de sélecteurs non désirées.
Bases : comment utiliser @extend
Voici un exemple de base où .btn--primary hérite des styles de .btn. @extend est une directive qui étend le sélecteur cible.
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}- En utilisant
@extend,.btn--primaryhérite des styles de base de.btnet ne modifie que les parties nécessaires.
CSS généré
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}Bonne pratique : utilisation des placeholders (%placeholder)
Les sélecteurs de type placeholder (%name) sont des sélecteurs qui ne sont pas générés dans le CSS. Ils sont largement utilisés, notamment lorsque vous souhaitez partager en toute sécurité des styles communs exclusivement pour l’héritage entre plusieurs composants.
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}.cardet.panelhéritent tous deux de%card-base, ce qui permet de partager des styles communs tout en ajoutant des différences si besoin.
CSS généré
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}Héritage multiple (plusieurs @extend)
Il est possible d’hériter de plusieurs placeholders ou classes en même temps. Bien que la réutilisabilité des styles soit améliorée, il est important de suivre quelles règles sont combinées avec quels sélecteurs.
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}- Voici un exemple où un bouton hérite de deux placeholders, un pour la 'base' et un pour la 'taille'.
.btn--lghérite à la fois de%btn-baseet de%btn-large, combinant ainsi la mise en page de base avec une taille plus grande.
CSS généré
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}Comportement de @extend (mécanisme de fusion) et précautions contre l’« explosion des sélecteurs »
@extend génère tous les sélecteurs correspondants fusionnés ensemble, ce qui peut parfois entraîner des combinaisons de sélecteurs non prévues.
L'exemple suivant montre comment la sortie peut augmenter lorsqu'une même classe de base est étendue à plusieurs endroits.
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}- Lorsque plusieurs composants héritent de
.utility, les sélecteurs sont fusionnés en un seul et, dans de grands projets, cela peut faire gonfler le CSS.
CSS généré
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 et .class contre sélecteurs d’éléments (balises) — Priorité et effets secondaires
@extend peut être appliqué non seulement aux classes mais aussi aux sélecteurs d’éléments. Cependant, l’extension des éléments élargit la portée concernée, augmentant le risque que des règles soient appliquées involontairement à des endroits non souhaités.
Voici un exemple d’extension d’un sélecteur d’élément et l’effet que cela peut avoir.
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*/- Dans cet exemple, hériter du sélecteur d’élément
h1fait que.titleest fusionné avec les mêmes styles queh1. - Cela peut sembler pratique dans des cas de petite taille, mais au fur et à mesure que votre projet grandit, des règles pour
h1pourraient se combiner de manière inattendue avec.title, rendant les styles plus complexes et moins maintenables. Par conséquent, concevoir principalement les styles autour des classes et des placeholders les rend plus faciles à maintenir.
CSS généré
1h1,
2.title {
3 font-size: 2rem;
4 margin-bottom: 0.5rem;
5}
6
7.title {
8 color: #333;
9}Cas d'utilisation de @extend et !optional
Si vous spécifiez !optional avec @extend, vous pouvez supprimer les erreurs lorsque la cible de l’héritage n’existe pas. Ceci est particulièrement utile dans un code de type bibliothèque ou dans les cas où les placeholders sont définis de manière conditionnelle.
Voici un exemple d’essai sécurisé d’héritage d’une classe pouvant ne pas exister, à l’aide de !optional.
1/* Try to extend a class that might not exist */
2.component {
3 @extend .maybe-existing !optional;
4 padding: 1rem;
5}- Si
.maybe-existingn’existe pas, rien ne se produit et cela est simplement ignoré. Vous pouvez utiliser cela lorsque vous souhaitez faire une extension de manière sûre.
CSS généré
1.component {
2 padding: 1rem;
3}Comparaison entre @extend et les mixins (@mixin / @include)
@extend et @mixin servent parfois à des fins similaires, mais leur sortie et leurs cas d'utilisation différent.
-
@extend- Le CSS généré réduit la redondance en fusionnant les sélecteurs.
- Comme les sélecteurs sont fusionnés après la génération, des combinaisons non désirées peuvent survenir.
- Vous ne pouvez pas passer de paramètres (mais cela peut être compensé en combinant les placeholders).
-
@mixin/@include- Chaque appel duplique les styles (engendrant une sortie redondante).
- Vous pouvez passer des paramètres et inclure de la logique comme des conditions ou des boucles.
- La sortie est plus prévisible, mais la taille du fichier augmente.
Voici une comparaison utilisant à la fois @mixin et @extend pour implémenter les mêmes styles de bouton.
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}@mixinpermet d'insérer des styles de manière flexible, alors que@extendconsolide la sortie efficacement, vous pouvez donc utiliser l’une ou l’autre selon le cas d’usage.
CSS généré
Sortie de @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}Sortie de @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}Consignes pratiques
L’héritage dans SASS est une fonctionnalité puissante pour augmenter la réutilisabilité des styles. Cependant, une mauvaise utilisation peut rendre la fusion des styles complexe et réduire la maintenabilité. Voici quelques points clés pour utiliser l’héritage de manière sûre et efficace.
- Utilisez les placeholders pour les styles purement communs des composants, tels que la structure et la mise en page. De plus, si une paramétrisation dynamique est nécessaire, vous pouvez utiliser
@mixin. - Vous devriez éviter d’hériter directement d’éléments HTML tels que
h1. Des combinaisons de sélecteurs imprévues peuvent survenir, pouvant entraîner la génération d’un CSS inattendu. - Utiliser des conventions de nommage comme BEM ou des préfixes clairs pour indiquer l’usage de chaque placeholder aide à garantir la sécurité.
- Il est plus sûr d’utiliser
@extenddans le même fichier. Surtout dans les grands projets, il est recommandé de concevoir l’héritage dans le cadre de chaque composant pour faciliter le suivi des relations d’héritage.
Résumé
La fonctionnalité @extend dans SASS est un moyen pratique de réutiliser efficacement les styles communs et de garantir la cohérence du design. Cependant, comme les combinaisons de sélecteurs peuvent rapidement devenir complexes, il est nécessaire d’utiliser cette fonctionnalité avec précaution et dans un cadre limité. En regroupant les styles partagés avec des sélecteurs placeholders (%placeholder) et en utilisant @mixin pour les parties nécessitant des paramètres dynamiques, vous pouvez maintenir un design simple et facile à maintenir.
Vous pouvez suivre l'article ci-dessus avec Visual Studio Code sur notre chaîne YouTube. Veuillez également consulter la chaîne YouTube.