Mi az SCSS? - "HTML, CSS, JS már megy. És most...?" - 2. rész

Mi az SCSS? - "HTML, CSS, JS már megy. És most...?" - 2. rész

Közzétéve: 

"HTMM, CSS, JS már megy. És most...?" - Ebben a sorozatban azt fogjuk átvenni, hogy mik következnek akkor, ha már össze tudsz rakni egy egyszerű weboldalt HTML, CSS és Vanilla JS segítségével. Ebben a részben az SCSS alapjairól fogunk beszélni.

Az SCSS egy olyan eszköz, ami segít neked átláthatóbb, és komplexebb CSS-t írni. Sok funkcióval felruház téged, amit a sima CSS nem képes megadni, viszont mivel a böngésző nem tudja kezelni a .scss fájlokat, így végül a te SCSS kódodat le fog fordulni CSS-re. Röviden: minden pluszt megkapsz, bármilyen hátrány nélkül 😉

Sass vs SCSS - Mi a különbség?

A Sass és az SCSS ugyanannak a fejlesztő csapatnak köszönhető, és a funkcióik azonosak, csak a szintaxis eltérő. Én az SCSS-t taglalom a cikkben, mivel sokkal népszerűbb a Sass-nél. Ez annak köszönhető, hogy az SCSS egy superset-je - "tartalmazó" halmaza a sima CSS-nek.

Ez azt jelenti, hogy bármely CSS kód teljesen valid SCSS kód is egyben. Az SCSS viszont kínál a sima CSS-en felül különleges funkciókat is, amik nagyon sokat segítenek a munkában. Ennek köszönhetően nagyon egyszerű elkezdeni a munkát, hiszen nem kell mindent tudnod, elég ha apránként használod az általa nyújtott funkciókat.

Setup - hogyan kezdjünk neki?

A következő szekciókban tanultakhoz fontos, hogy te is velem csináld a lépéseket, így először be kell üzemelni a fordítást az SCSS és CSS között.

  1. Inicializáljunk egy projektet: npm init -y
  2. Telepítsük globálisan a sass csomagot: npm i -g sass
  3. Hozzunk létre két fájlt: egy index.html-t és egy source.scss fájlt.
  4. A HTML fájlba illesszük be az alap html boilerplate-et. (Visual Studio Code esetén ezt a felkiáltójel snippet beilleszti).
  5. Adjunk hozzá egy <link rel="stylesheet" href="styles.css"/> tag-et a <head>-hez. (Ez a fájl még nem létezik, mert majd a fordító fogja létrehozni.)
  6. Indítsunk el egy egyszerű szervert, hogy a böngészőben is lássuk a fájljainkat: npx serve .
  7. Egy másik terminálban indítsuk el az SCSS fordítónkat: sass --watch source.scss styles.css. Itt három dolgot is megadtunk a sass parancsnak:
    1. --watch: ez a flag azt mondja a sass-nek, hogy folyamatosan figyelje a változásokat az .scss fájlunkban, és ha bármi változik, akkor azonnal futtassa le újra a fordítást.
    2. source.scss: ez a bemeneti fájlunk. Ezt szeretnénk lefordítani.
    3. styles.css: ez a kimeneti fájlunk. Ide szeretnénk, hogy lefordítsa az SCSS-ünket.
  8. Kész! A sass fordítja a fájlunkat, és a szerver üzemel. Az első terminal-ban megjelent az URL, amit megnyithatunk a böngészőnkben (általában http://localhost:3000)

1. Változók

Az SCSS segítségével definiálhatunk változókat, amelyeket elég egyszer definiálni, így ha az oldalon mindenhol változtatni akarjuk az egyik színt, akkor azt elég egy helyen átírni, a deklarációnál.

Változókat a $ karakterrel tudunk létrehozni, és a CSS-ben megszokott : operátorral rendelhetünk hozzájuk értéket.

$custom-color: #f1f1f1;
$custom-gradient: linear-gradient(to right, #16aa91, $custom-color);
$my-padding-1: 1rem;

body {
  background-color: $custom-color;
}

h1 {
  background-image: $custom-gradient;
  color: $custom-color;
  padding: $my-padding-1;
}

(Ez a funkció a CSS custom properties (variables) megjelenésével és elterjedésével egyre kevésbé hasznos, szóval ha csak emiatt használnánk az SCSS-t, akkor érdemes ezeknek is utánajárni.)

2. Nesting - "Egymásba ágyazás"

A CSS-ben sokszor komplex selectorokat építünk, hogy kiválasszuk, a megcélzott elemet.

Vegyünk egy példát: Szeretnénk, ha minden <article> tagbena betűtípus sans-serif lenne, a benne létező <p> tagek sorköze 1.5 lenne, illetve minden ilyen p-ben szereplő kép szélessége 75% lenne.

Ezt CSS-ben így adhatjuk meg:

article {
  font-family: sans-serif;
}

article p {
  line-height: 1.5;
}

article p img {
  width: 75%;
}

Az SCSS-ben viszont ezeket egybeágyazhatjuk, így nem kell többször kiírni, hogy article, illetve p:

article {
  font-family: sans-serif;
  
  p {
    line-height: 1.5;
    
    img {
      width: 75%;
    }
  }
}

A lefordított .css fájlban ez a kód ugyanúgy az első (CSS) kódra fog lefordulni, viszont nekünk nem kell azt a bonyolult kódot nézni miközben szerkesztjük a kódot. Sokat segít az átláthatóságán, illetve kevesebbet is kell manuálisan begépelni. itt egy bonyolultabb példa is:

Azt szeretnénk, hogy a one, two, three, four, five osztályokon belül közvetlenül szereplő <article> piros legyen:

CSS:

.one > article, .two > article, .three > article, .four > article, .five > article {
  color: red;
}

Ezzel szemben az SCSS:

.one, .two, .three, .four, .five {
  & > article {
    color: red;
  }
}

Ugye hogy sokkal átláthatóbb?

Na de mi az az & karakter ott a kódban?

Az & karakter a szülőt jelöli, tehát azt/azokat az elemeket, amikbe be van ágyazva az adott sor. Ha nem használjuk ezt a karaktert, akkor az SCSS úgy fordítja, mintha csak szóköz lenne közöttük. Mivel egész sok CSS selector, pseudo-selector, és pseudo-element létezik, így az & jelet sokszor kell használni majd.

Például ha a ::before pseudo-elementet célozzuk meg, akkor ki kell tennünk elé az & jelet, különben az elvárt (pl.: p::before) helyett arra fog fordulni a kód, hogy p ::before, ami nem egyezik meg az elvárásunkkal.

3. Mixinex

A mixinek segítségével sok ismétlést tudunk elkerülni a kódunkban. A JS-ből ismerős függvényekhez hasonlóan a mixineknek is vannak argumentumai, amelyeket használhatunk a kódunkban.

Példa: Szeretnénk egy <div>-ből egy kört készíteni, aminek állítható a mérete és a színe.

CSS-ben mindenhol újra és újra be kell másolnunk, a szabályokat, és ha valamivel ki szeretnénk bővíteni, akkor egyesével szerkeszthetjük őket.

SCSS-ben viszont egy mixin segítségével csak egyszer definiáljuk, és utána újrahasználhatjuk az @include segítségével:

@mixin circle($diameter, $bg) {
  width: $diameter;
  height: $diameter;
  border-radius: 50%;
  background: $bg;
}

.big-red-circle {
  @include circle(10rem, #ff4747);
}

// Az argumentumok megadásakor megadhatjuk az argumentumok nevét is.
.small-green-circle {
  @include circle($diameter: 5rem, $bg: #47ff47);
}

4. A @use szabály

A @use szabály más .scss fájlokból tölt be függvényeket, mixineket, és változókat, illetve más fájlok CSS szabályait is betölti. Az ilyen módon betöltött fájlokat moduloknak hívjuk.

A @use szabálynak minden CSS szabály előtt kell megjelennie. A betöltött modul CSS szabályai automatikusan betöltődnek, a függvényeket, változókat és mixineket pedig úgy nevezett namespace-eken keresztül érhetjük el.

Ha betöltjük például a _base.scss fájlt a @use 'base' paranccsal, akkor a base namespace-t használhatjuk a benne lévő változók elérésére.

A _base.scss fájl tartalma:

$primary-color: #3ab564;

@mixin reset-link($color: $primary-color) {
  text-decoration: none;
  color: $color;
}

Az a fájl, amiben betöltjük:

@use 'base';

button {
  background-color: base.$primary-color;
}

a {
  @include base.reset-link;
}

Ha a _base.scss fájlból akarunk betölteni valamit, de nem a base namespace-szel akarjuk használni a benne lévő változókat, akkor az as kulcsszó segíthet.

@use 'base' as b;
// vagy
@use 'base' as *; // ha namespace nélkül használnánk

5. Map-ok, List-ek

Létezik két különleges adattípus SCSS-ben: a map, és a list. Kezdjük a listtel:

A list hasonlít a JS Array-re, ugyanis sorban tárol értékeket. Ezeken végig iterálhatunk, és (többek között) osztályneveket generálhatunk velük. Az iterálást a következő pontban vesszük át, de itt egyszerű lesz a példa:

$alignments: right, left;

@each $direction in $alignments {
    .text-align-#{$direction} {
        text-align: $direction;
    }
}

Ez a kód ezt a CSS-t generálja:

.text-align-right {
  text-align: right;
}

.text-align-left {
  text-align: left;
}

Egyszerűen végigmegyünk a lista értékein, és felhasználjuk az értéket az osztály nevében, és a text-align értékének.

Talán sokkal gyakoribb eszközök a map-ok, amik kulcs-érték párosokat tartalmaznak. Egy map-ot zárójelek között tudunk létrehozn, vesszőkkel elválasztva. Például így:

$breakpoints: (
    "sm": 500px,
    "md": 650px,
    "lg": 900px
);

Ezen is végig tudunk iterálni, viszont itt két értéket is kapunk iterációnként: a kulcsot, és a hozzá rendelt értéket.

Így ha például generálni szeretnénk különböző méretű .container-<név> osztályokat, akkor ezt így tehetjük meg:

$breakpoints: (
    "sm": 500px,
    "md": 650px,
    "lg": 900px
);

@each $key, $value in $breakpoints {
    .container-#{$key} {
        max-width: $value;
    }
}

Ebből ezek a CSS osztályok generálódnak:

.container-sm {
  max-width: 500px;
}

.container-md {
  max-width: 650px;
}

.container-lg {
  max-width: 900px;
}

6. Ciklusok, if-else és függvények

A programozásban sokszor használunk ciklusokat, és az if-else párost. Ezek olyankor is hasznosak lehetnek, amikor sok osztályt akarunk generálni.

Alább bemutatok egy kissé bonyolultabb kódot, ami osztályokat, és azok szabályait fogja generálni. Kicsit komplex lesz, de alább végig magyarázom.

$colors-map: (
  'red': #dc2626,
  'green': #86efac,
  'teal': #14b8a6,
);

@each $color-name, $color-value in $colors-map {
  .text-#{$color-name} {
    color: $color-value;
    @if lightness($color-value) >= 70% {
      background-color: #000000;
    } @else {
      background-color: #ffffff;
    }
  }
}

1-5. sor: Létrehozunk egy szín-mapot.

7. sor: Végigmegyünk minden színen a map-ban, és kibontjuk a kulcsot a $color-name, az értéket pedig a $color-value változókba.

8. sor: Létrehozunk egy osztály szabályt, a szín nevével. Itt a változó beillesztésére a #{} szintaxist használjuk. Ebből ezek lesznek: .text-red, .text-green, és .text-teal.

9. sor: Az adott osztályban az adott színt állítjuk be a color értékének.

10-14. sor: A lightness() függvénnyel ellenőrizzük, hogy az adott szín világossága nagyobb-e 70%-nál. Ha világosabb a szín, akkor a szöveg kap egy fekete hátteret, ellenkező esetben egy fehér hátteret kap, hogy minden szín olvasható maradjon bármilyen háttéren.

Szerintem ez eleget megmutat bevezetésként, a pontos részleteket az egyes Flow control elemekkel kapcsolatban itt találhatod meg.

A függvények szintén komplex operációkat tesznek röviddé, és olvashatóvá. Az SCSS sok beépített függvényt tartalmaz, és te is írhatsz saját függvényeket. A saját függvények túlmutatnak ennek a cikknek a szkópján, viszont ha érdekel, itt utánajárhatsz.

Én ezeket tartottam fontosnak az SCSS-sel kapcsolatban. Köszönöm, hogy velem tartottál, és remélem, hogy segíteni fog téged a munkádban!

A sorozat következő részében a Node.js-szel fogunk megismerkedni, és annak felhasználásával a serverless környezetekben.

Források:


Komment szekció