ירושה ב-SASS

ירושה ב-SASS

מאמר זה מסביר ירושה ב-SASS.

נסביר ירושה ב-SASS עם דוגמאות מעשיות.

YouTube Video

ירושה ב-SASS

ירושה ב-SASS (@extend) היא מנגנון שמאפשר להחיל סגנון של סלקטור אחד על אחר ללא כפילות. מכיוון שאותם סגנונות 'משולבים' ויוצאים לקוד עבור אלמנטים מרובים, ה-CSS שנוצר פחות סובל מסרבול; אך שימוש לא נכון עלול להוביל למיזוגים לא צפויים של סלקטורים.

בסיס: כיצד להשתמש ב-@extend

להלן דוגמה בסיסית שבה .btn--primary יורש את הסגנונות של .btn. @extend היא הוראה שמרחיבה את הסלקטור המיועד.

 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}
  • באמצעות @extend, .btn--primary יורש את סגנונות הבסיס של .btn ומשנה רק את החלקים הנדרשים.

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}

מנהג נכון: שימוש בפלייסהולדרים (%placeholder)

סלקטורים של מצייני מקום (%name) הם סלקטורים שאינם יוצאים ל-CSS. הם בשימוש נרחב במיוחד כאשר רוצים לשתף סגנונות משותפים בבטחה לצורך ירושה בין מספר רכיבים.

 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 והן .panel יורשות מ-%card-base, כך שהן משתפות סגנונות בסיסיים ומתאימות אותם בעת הצורך.

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}

ירושה מרובה (@extend מרובים)

ניתן לרשת כמה פלייסהולדרים או מחלקות בו־זמנית. למרות ששימוש חוזר בסגנון משתפר, חשוב לעקוב אחרי אילו כללים משולבים עם אילו סלקטורים.

 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}
  • זו דוגמה שבה לחצן יורש שני פלייסהולדרים: אחד לבסיס ואחד לגודל.
  • .btn--lg יורש הן את %btn-base והן את %btn-large, ומשלב פריסה בסיסית עם גודל גדול יותר.

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 (מנגנון מיזוג) וזהירות מ'פיצוץ סלקטורים'

@extend מוציא את כל הסלקטורים התואמים כממוזגים, דבר שיכול להוביל לשילובים בלתי רצויים של סלקטורים.

הדוגמה הבאה מדגימה כיצד הפלט גדל כאשר אותה מחלקת בסיס מורחבת בכמה מקומות.

 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}
  • כאשר מספר רכיבים יורשים את .utility, הסלקטורים מתמזגים ובפרויקטים גדולים ה-CSS עלול להתנפח.

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 ו-.class מול סלקטורי תגיות — עדיפויות ותופעות לוואי

@extend ניתן להחיל לא רק על מחלקות אלא גם על סלקטורים של אלמנטים. עם זאת, הרחבת אלמנטים מגדילה את תחום ההשפעה, מה שמעלה את הסיכון שכללים יוחלו בטעות במקומות לא מתוכננים.

להלן דוגמה להרחבת סלקטור של תגית והשפעתה.

 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*/
  • בדוגמה זו, ירושה מהסלקטור של h1 גורמת ל-.title לקבל את אותם סגנונות כמו h1.
  • אמנם זה עלול להיראות נוח במקרים קטנים, אך כאשר הפרויקט גדל, הכללים עבור h1 עלולים להתמזג באופן לא צפוי עם .title, מה שמסבך את הסגנונות ומפחית את התחזוקתיות שלהם. לכן, עיצוב סגנונות סביב מחלקות ומצייני מקום בעיקר, מקל על תחזוקתם.

CSS שנוצר

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

שימושים עבור @extend ו-!optional

אם תציין !optional עם @extend, תוכל לדכא שגיאות כאשר יעד הירושה לא קיים. דבר זה שימושי במיוחד בקוד שנראה כמו ספריה או במקרים בהם מצייני מקום מוגדרים בתנאי.

הנה דוגמה לניסיון ירושה בטוח ממחלקה שאולי לא קיימת, תוך שימוש ב-!optional.

1/* Try to extend a class that might not exist */
2.component {
3  @extend .maybe-existing !optional;
4  padding: 1rem;
5}
  • אם .maybe-existing לא קיימת, לא מתרחש דבר וההוראה מדולגת. אפשר להשתמש בכך כאשר רוצים לנסות הרחבה באופן בטוח.

CSS שנוצר

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

השוואה בין @extend ומיקסים (@mixin / @include)

@extend ו-@mixin לעיתים בעלי מטרות דומות, אך ההוצאה והשימושים שלהם שונים.

  • @extend

    • ה-CSS שנוצר מפחית כפילויות על ידי מיזוג סלקטורים.
    • מכיוון שסלקטורים מתמזגים לאחר ההפקה, עשויים להיווצר שילובים בלתי רצויים.
    • לא ניתן להעביר פרמטרים (אם כי ניתן לפצות על כך על ידי שילוב פלייסהולדרים).
  • @mixin / @include

    • כל קריאה משכפלת את הסגנונות (ויוצרת פלט מיותר).
    • ניתן להעביר פרמטרים ולשלב לוגיקה כמו תנאים או לולאות.
    • הפלט צפוי יותר, אך נפח הקובץ גדל.

להלן השוואה של שימוש ב-@mixin וב-@extend ליישום אותם סגנונות ללחצן.

 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 מאפשר הוספת סגנונות בצורה גמישה, בעוד ש-@extend מאחד פלט ביעילות; אפשר להשתמש בכל אחד בהתאם למקרה.

CSS שנוצר

פלט מ-@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}
פלט מ-@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}

הנחיות מעשיות

הירושה ב-SASS היא תכונה עוצמתית להגדלת השימושיות החוזרת של הסגנונות. אבל שימוש לא נכון עלול לסבך את מיזוג הסגנונות ולפגוע בתחזוקה. להלן כמה נקודות מפתח לשימוש בירושה באופן בטוח ויעיל.

  • השתמש במצייני מקום עבור סגנונות רכיבים משותפים לחלוטין, כגון מבנה ופריסה. בנוסף, אם דרושה פרמטריזציה דינמית, תוכל להשתמש ב-@mixin.
  • עליך להימנע מירושה ישירה של אלמנטים ב-HTML כמו h1. עלולות להיווצר קומבינציות סלקטור לא מתוכננות, שעשויות לגרום להפקת CSS לא צפוי.
  • שימוש בנוהלי שמות כמו BEM או תחיליות ברורות שמסבירות את מטרת כל פלייסהולדר שומר על בטיחות הקוד.
  • בטוח יותר להשתמש ב-@extend בתוך אותו קובץ. במיוחד בפרויקטים גדולים, מומלץ לעצב ירושה בתוך התחום של כל רכיב כדי להקל על מעקב אחרי יחסי הירושה.

סיכום

התכונה @extend ב-SASS היא דרך נוחה לשימוש חוזר ויעיל בסגנונות משותפים ולהבטיח אחידות עיצובית. אולם, מאחר שקל יחסית לקבל קומבינציות סלקטור מורכבות, יש להשתמש בתכונה זו בזהירות ובתחום מוגבל. על ידי קיבוץ סגנונות משותפים עם סלקטורי מצייני מקום (%placeholder) ושימוש ב-@mixin עבור חלקים שדורשים פרמטרים דינמיים, תוכל לשמור על עיצוב פשוט וקל לתחזוקה.

תוכלו לעקוב אחר המאמר שלמעלה באמצעות Visual Studio Code בערוץ היוטיוב שלנו. נא לבדוק גם את ערוץ היוטיוב.

YouTube Video