איך ולמה להתחיל להשתמש ב Scss

25/03/2019

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

שפת Sass, שזה קיצור ל Syntactically awesome style sheets היא שפה שנועדה להוסיף מנגנונים של שימוש חוזר בחלקים מהקוד ל CSS. היא נכתבה על ידי הנרי תורנטון ונמצאת איתנו מ 2006. בזכות תאימות מלאה ל CSS קל מאוד להתחיל להשתמש בה וכך לאט לאט לשפר את קוד ה CSS שלכם. כל העבודה עם Sass מתבצעת בצד השרת לפני שהקבצים מגיעים לדפדפן ולכן מבחינת הדפדפן זה שקוף לגמרי. לגולש אין מושג אם אתם משתמשים ב CSS או ב Scss.

ביום חמישי הקרוב אעביר וובינר של שעה על Scss - החל מכלי העבודה הבסיסיים ודרך הרבה מהיכולות של השפה. מוזמנים בחום להצטרף (זה בחינם). המשך הפוסט הוא תקציר של מה שהולך להיות בוובינר. זה הקישור להצטרפות:

https://www.tocode.co.il/workshops/72

1. מה ההבדל בין Sass ל Scss

נתחיל עם מושגים - בשנת 2006 הנרי תורנטון ונטלי ויזנבאום הבינו ש CSS זה לא כזה כיף (ואם נהיה הוגנים ב 2006 CSS עוד היה הרבה פחות כיף ממה שהוא היום). במקור הם תיכננו להשתמש בכתיב שונה לגמרי מזה של CSS ולהחליף את הסוגריים המסולסלים באינדנטציה, קצת כמו פייתון. זה נראה ככה:

body
  background: orange
  color: white

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

ויזמן ותורנטון חזרו לשולחן השירטוטים ויצרו את Scss - תחביר חדש ותואם לחלוטין ל CSS. אותו הבלוק שראינו קודם ב Sass יהיה כתוב ב Scss ככה:

body {
    background: orange;
    color: white;
}

מה שאומר שאם אתם יודעים CSS אתם כבר יודעים גם Scss. כל קוד CSS שתקחו הוא גם קוד Scss, ואתם יכולים לקחת את המערכת שלכם כמו שהיא, לשנות את כל סיומות הקבצים מ css ל scss, ויש לכם פרויקט Scss.

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

2. הגדרות הפרויקט

לא מעט Web Frameworks מגיעות כבר עם תמיכה מובנית ב Scss או שאפשר להוסיף את התמיכה בקלות בתוך הכלים של הפריימוורק. אני רוצה להראות כאן מנגנון פשוט שעובד בכל מצב ומאפשר לעבוד עם Scss בכל פרויקט בעולם, בין אם הפריימוורק שלכם תומך או לא תומך בכתיב זה.

הדרך הקלה לעבוד עם Scss היא להפוך את כל קבצי ה scss בפרויקט לקבצי css רגילים. יש כלי בשם sass שעושה בדיוק את זה ואתם יכולים להתקין אותו דרך npm עם הפקודה:

npm install -g sass

דרך עוד יותר קלה לעבוד עם Scss היא להתקין אפליקציה גרפית בשם Koala. קואלה הוא יישום קוד פתוח שלוקח פרויקט והופך באופן אוטומטי את כל קבצי ה scss בפרויקט לקבצי css. אתם יכולים להתקין את קואלה מכאן:

http://koala-app.com/

אחרי ההתקנה כדאי ליצור קובץ הגדרות פרויקט בו תגידו לקואלה באיזה תיקיה נמצאים קבצי ה scss שלכם ולאיזה תיקיה תרצו לשמור אותם בתור css. שם קובץ ההגדרות הוא koala-config.json וצריך לשמור אותו בתיקיה הראשית של הפרויקט. אפשר להשתמש בתבנית הבאה בשביל תוכן הקובץ:

// Sass project settings, you can edit it and set custom settings.
{
    // The mappings of source directory and output directory
    "mappings": [
        {
            "src": "scss",
            "dest": "css"
        }
    ],

    // Add the ignore rules that Koala will not search them.
    // e.g. ["*.json", "*.txt", "test", "path/libs"]
    "ignores": ["*.css"],

    // Compile options of Sass.
    "options": {

        // Output style. Can be nested (default), compact, compressed, or expanded.
        "outputStyle": "nested",

        // Emit comments in the generated CSS indicating the corresponding source line.
        "lineComments": false,

        // Emit extra information in the generated CSS that can be used by the FireSass Firebug plugin.
        "debugInfo": false,

        // Create sourcemap files next to the generated CSS files
        "sourceMap": false,

        // Use Unix-style newlines in written files.
        "unixNewlines": false,

        // auto add vendor prefixes to rules
        "autoprefix": false,
        "autoprefixConfig" : "> 1%, last 2 versions, Firefox ESR, Opera 12.1"
    },

    // Other compile options, use the full name of options.
    // e.g, ["--scss", ... ,"--no-cache"].
    // Run the command 'sass -h' to see more options.
    "customOptions": [],

    // An array of filesystem paths or importers which should be searched for Sass templates imported with the @import directive.
    "includePaths": [],

    // A array of ruby libraries, require them before running Sass.
    "requireLibs": []
}

החלק המעניין בתבנית הזאת הוא הבלוק הראשון שנקרא mapping. שם כתבתי את התיקיה בה אני שומר את קבצי ה scss שלי ואת התיקיה אליה אני רוצה שקואלה יכתוב את קבצי ה css. עץ הפרויקט שמתאים להגדרות נראה ככה:

$ tree
.
├── css
│   └── main.css
├── index.html
├── koala-config.json
└── scss
    └── main.scss

תוכן הקובץ main.scss:

body {
  background: green;
}

ותוכן הקובץ index.html:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Index</title>
    <link rel='stylesheet' href='css/main.css'  />
  </head>
  <body>

  </body>
</html>

אחרי שיש לכם את כל הקבצים במקום מפעילים את קואלה, בוחרים את תיקיית הפרויקט ורואים איך באופן אוטומטי קואלה יוצר את הקובץ main.css בתיקיה css. בשלב זה תוכן הקובץ כמעט זהה לתוכן הקובץ main.scss מאחר ולא השתמשתי עדיין באף יכולת של Scss.

3. ניצחונות קלים

רק עד לפה יש לנו תשתית לפרויקט Scss - אבל מה אפשר לעשות עם זה? מה זה נותן יותר מאשר CSS? אז קודם כל ב Scss אתם יכולים לכתוב Selectors מקוננים בצורה מקוננת גם בקובץ. למשל קוד ה Scss הבא:

.menu {
  list-style: none;

  a {
    text-decoration: none;
    padding: 10px;
  }
}

ובמעבר ל CSS זה יהפוך לקוד הבא:

.menu {
  list-style: none;
}

.menu a {
  text-decoration: none;
  padding: 10px;
}

הסימן המיוחד & מאפשר להתיחס לכלל ה CSS בתוכו אני כותב עכשיו את התוכן, וזאת דרך מסורבלת להגיד שהקטע הבא:

a {
  color: red;

  &:focus, &:hover {
    border: 1px solid blue;
  }
}

הוא Scss תקין שיהפוך ל CSS הבא:

a {
  color: red;
}

a:focus, a:hover
{
    border: 1px solid blue;
}

רעיון נחמד שני שיש לנו הוא הערות - אם אתם זוכרים ב CSS כשאתם כותבים הערה היא נשלחת במלואה ללקוח כי היא כתובה בתוך ה CSS. ב Scss אנחנו יכולים לכתוב הערה שתישמר רק בקובץ ה Scss אבל לא תיכתב לקובץ ה CSS, פשוט מתחילים שורה עם לוכסן כפול. קוד ה Scss הבא:

body {
  // I love green
  background: green;
}

יהפוך ל CSS הזה:

body {
  background: green; }

והרעיון השלישי לפני שנצלול לעומק ה Scss הוא משתנים. אז נכון שהיום יש כבר משתני CSS אבל תהיו עדינים כי כשרק התחילו לכתוב את Scss הם לא היו. בכל מקרה המשתנים ב Scss יגרמו לקוד הזה:

$fg: orange;
$bg: white;

body {
  background: $bg;
  color: $fg;
}

.inverse {
  background: $fg;
  color: $bg;
}

להפוך ל CSS הרגיל לגמרי הזה:

body {
  background: white;
  color: orange;
}

.inverse {
  background: orange;
  color: white;
}

4. הפרדה לוגית לקבצים

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

ב Scss אנחנו יכולים לשבור את הקשר הזה. אפשר לחלק את הפרויקט לקבצים לפי מה שמסתדר לכם לוגית ובאופן אוטומטי Scss יאחד את הקבצים לקובץ אחד לפי פקודות ה import.

נחזור לפרויקט שלנו ונוסיף עוד 3 קבצים:

  1. _menu.scss
  2. _layout.scss
  3. _typography.scss

שימו לב שכל אחד מהקבצים מתחיל בסימן קו תחתי. סימן זה אומר ל Scss שזהו קובץ שעושים לו import מתוך קובץ אחר. רישמו מספר פקודות CSS בתוך כל אחד מהקבצים ואז בקובץ הראשי רישמו:

@import 'layout';
@import 'menu';
@import 'typography';

ותוכלו לראות שהתוכן של כל שלושת הקבצים הודבק לתוך קובץ ה CSS שלכם. בזכות Scss אתם יכולים להחליט איזה קבצי CSS יוגשו למשתמש (הקבצים שלא מתחילים בקו תחתי) ואיזה קבצי CSS הם שם רק בשביל שהקוד שלכם יהיה מסודר.

5. משתנים וערכים מחושבים

אחד הדברים שהופכים משתני Scss למעולים הוא היכולת לחשב ערכים נגזרים. נחזור להגדרה שכבר ראינו לגבי צבע רקע וצבע טקסט:

$fg: orange;
$bg: white;

body {
  background: $bg;
  color: $fg;
}

עכשיו נניח שיש לי ריבוע ביישום שאני רוצה שיהיה בצבע קצת יותר כהה מצבע הרקע. במקום לחשב לבד את ערך הצבע אני יכול לתת ל Scss לעשות את העבודה:

$fg: orange;
$bg: white;

body {
  background: $bg;
  color: $fg;
}

.box {
  background: darken($bg, 5);
}

והתוצאה היא ה CSS הבא:

body {
  background: white;
  color: orange; }

.box {
  background: #f2f2f2; }

המספר שעובר ל darken מציין בכמה אחוז להפוך את הצבע לכהה יותר, והוא נע בין 0 ל 100. אגב יש גם פונקציה בשם lighten שעושה את העבודה ההפוכה.

מנגנון חישוב נוסף מתיחס ליחידות מידה וגדלים. הרבה פעמים אני ארצה לחבר בין גודל הגופן, גודל התיבה וגודל השוליים. בעזרת Scss אפשר לעשות את החיבור הזה בקלות. קוד ה Scss הבא:

$font-size: 18px;

.menu {
  a {
    font-size: $font-size;
    padding: $font-size / 2;
    margin: $font-size / 6;
  }
}

יהפוך לקוד ה CSS הבא:

.menu a {
  font-size: 18px;
  padding: 9px;
  margin: 3px; }

6. פונקציות ב Scss

ל Scss יש די הרבה פונקציות מובנות במערכת, ואפשר למצוא את הרשימה המלאה שלהן בתיעוד. הנה כמה פונקצות שאני אוהב במיוחד, נתחיל עם פונקציות הקשורות לצבע:

  1. grayscale - הופכת צבע לגוון של אפור
  2. complement - מחזירה את הצבע המשלים לצבע מסוים
  3. invert - מחזירה את הצבע ההופכי לצבע מסוים
  4. lighen, darken - מחזירות צבע בהיר יותר או כהה יותר מצבע מסוים
  5. opacify, transparentize - מחזירות צבע אטום יותר או שקוף יותר מצבע מסוים

פונקציות הקשורות למספרים:

  1. round - מעגל מספר
  2. ceil, floor - מחזיר את המספר השלם הקרוב ביותר (מלמעלה או מלמטה) למספר מסוים
  3. min, max - מחזירות את המספר הגדול ביותר או הקטן ביותר מתוך סידרת מספרים

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

@function calc-percent($target, $container) {
  @return ($target / $container) * 100%;
}

אנחנו משתמשים בפונקציה בדיוק כמו שהיינו משתמשים בכל פונקציית מערכת של Scss, כך שהקוד הבא אחרי הגדרת הפונקציה:

.box {
  width: calc-percent(650, 1000);
}

הופך ל-CSS הבא:

.box {
  width: 65%; }

7. פקודות בקרה: if, for, each, while

ל Scss יש תמיכה מלאה בלולאות ותנאים. במקום לראות את כל הפקודות אני אראה כאן רק דוגמא קצרה ללולאת for, את השאר תוכלו למצוא בתיעוד. נניח שאנחנו רוצים להתאים את כל הגדלים של הכותרות לפי סדר מסוים, כך שכל h-מספר יהיה בגודל כפול 1.2 מזה שלפניו כלומר נרצה לקבל את ה CSS הזה:

h1 { font-size: 34.83648px; }
h2 { font-size: 29.0304px; }
h3 { font-size: 24.192px; }
h4 { font-size: 20.16px; }
h5 { font-size: 16.8px;
h6 { font-size: 14px; }

אז נוכל לכתוב את הלולאה הבאה ב Scss ולקבל את הכל במכה אחת ובלי חישובים ידניים:

$sz: 14px;
@for $i from 1 through 6 {
  h#{7 - $i} {
    font-size: $sz;
  }

  $sz: $sz * 1.2;
}

בדף הזה תמצאו עוד די הרבה דוגמאות לשימוש בפקודות הבקרה של Scss:

http://thesassway.com/intermediate/if-for-each-while

8. מיקסינים

היכולת האחרונה למדריך זה והמדליקה ביותר של Scss נקראת Mixins. מיקסינים הם קטעי CSS שאפשר "להדביק" בתוך קטעים אחרים וגם להעביר להם פרמטרים. מיקסינים הם המפתח ל Code Reuse מוצלח בין חלקים שונים בפרויקט.

אנחנו מגדירים מיקסין עם המילה השמורה @mixin, אחריה שם המיקסין ואז התוכן למשל:

@mixin large-text {
  font: {
    family: Arial;
    size: 20px;
    weight: bold;
  }
  color: #ff0000;
}

אחרי שיש לנו מיקסין מוגדר נוכל להשתמש בו באמצעות המילה השמורה @include למשל:

.page-title {
  @include large-text;
  padding: 4px;
  margin-top: 10px;
}

ובמכה אחת קיבלנו את כל כללי ה CSS שהוגדרו בתוך המיקסין.

מיקסינים יכולים גם לקבל פרמטרים ולכן הקטע הבא עובד:

@mixin my-small-rounded-corners($r:5px) {
    -moz-border-radius: $r;
    -webkit-border-radius: $r;
    border-radius: $r;
}

.rounded {
    @include my-small-rounded-corners(8px);
}

ומייצר את כללי ה CSS האלה:

.rounded {
  -moz-border-radius: 8px;
  -webkit-border-radius: 8px;
  border-radius: 8px;
}

ומיקסינים יכולים לקבל גם בלוקים ולפעול עליהם - מה שאומר שאנחנו יכולים לכתוב את המיקסין הבא:

@mixin small() {
    @media only screen and (max-width: 320px) {
        @content;
    }
}

ולהשתמש בו בצורה הזאת:

@include small {
    body { background: orange; }
}

ונקבל את כללי ה CSS:

@media only screen and (max-width: 320px) {
  body {
    background: orange;
  }
}

המילה השמורה @content קובעת איפה במיקסין ייכתב הבלוק, והיא שמאפשרת להגדיר מיקסינים עבור Media Queries.

9. סיכום

שפת Scss כוללת הרבה מאוד פינוקים למפתחי CSS שברוב המקרים יקלו עליכם מאוד את העבודה ויאפשרו לכם לתחזק בסיסי קוד גדולים בלי לשכפל קוד.

אני מזכיר שביום חמישי אני מתכנן להעביר פה שעה על Scss ושם נראה עוד הרבה דוגמאות ויהיה גם זמן לשאלות. מוזמנים להצטרף (בחינם) בקישור:

https://www.tocode.co.il/workshops/72