Kurs HTML i CSS · Moduł 7: SASS
Zmienne w Sass
W tej lekcji5
Paleta świątyni to kilkanaście wartości: złoto, lapis lazuli, kolor piasku, dwie czcionki i kilka odstępów. Jeśli każdą z nich wpisujesz ręcznie, przy pierwszej zmianie gubisz spójność, bo gdzieś zawsze zostanie stary odcień. Zmienne w Sass nadają każdej wartości imię, jak kartusz z imieniem faraona: zapisujesz je raz, a potem przywołujesz wszędzie tam, gdzie jest potrzebne. To potężne narzędzie, które ułatwia utrzymanie kodu i wprowadzanie zmian.
Definiowanie zmiennych
Zmienne w Sass zaczynają się od znaku dolara ($). Po nazwie stawiasz dwukropek, wartość i średnik. Możesz przypisać do nich różne wartości, takie jak kolory, długości, procenty, nazwy czcionek, wartości logiczne i inne. Oto trzy przykładowe deklaracje:
1$main-color: #c06;
2$font-stack: Helvetica, sans-serif;
3$base-line-height: 1.5;Mamy tu kolor, listę czcionek i liczbę bez jednostki. Same deklaracje nie wygenerują w CSS ani jednej linii, bo zmienna istnieje tylko w pliku źródłowym. Warto też wiedzieć, że w nazwach zmiennych Sass traktuje myślnik i podkreślenie tak samo, więc $font-stack i $font_stack to ta sama zmienna. Polecam Ci myślniki bo tak samo nazywamy właściwości w CSS.
Używanie zmiennych
Po zdefiniowaniu zmiennej umieszczasz jej nazwę wszędzie tam, gdzie chcesz użyć jej wartości, także obok innych wartości w jednej deklaracji:
1body {
2 color: $main-color;
3 font: 100% $font-stack;
4 line-height: $base-line-height;
5}Kompilator podmieni każdą zmienną na jej wartość, więc w CSS zobaczysz color: #c06, a skrót font otrzyma wartość 100% Helvetica, sans-serif. Reguła body wygląda po kompilacji dokładnie tak, jakbyś wpisał te wartości ręcznie.
Zasięg zmiennych
Zmienne w Sass mają zasięg, co oznacza, że są dostępne tylko w obrębie bloku, w którym zostały zdefiniowane. Jeśli zdefiniujesz zmienną na najwyższym poziomie, poza jakimikolwiek selektorami czy regułami, jest ona globalna i możesz jej używać w całym arkuszu stylów. Jeżeli jednak zdefiniujesz zmienną wewnątrz reguły lub selektora, będzie ona dostępna tylko w tym bloku, jak skarb zamknięty w jednej komnacie:
1$global-color: blue;
2
3.foo {
4 $local-color: green;
5 color: $local-color; // zielony
6}
7
8.bar {
9 color: $local-color; // błąd, $local-color nie jest dostępne tutaj
10}Reguła .foo dostanie zielony kolor, ale przy .bar kompilacja zakończy się błędem, bo zmienna $local-color nie istnieje poza blokiem .foo. Zmienna $global-color pozostaje dostępna w obu regułach.
Sass pozwala też użyć tej samej nazwy ponownie. Jeśli wewnątrz selektora zadeklarujesz zmienną o nazwie zmiennej globalnej, powstanie zmienna lokalna, która przesłoni globalną tylko w tym bloku, a poza nim globalna wartość się nie zmieni. Flaga !global pozwala celowo nadpisać zmienną globalną z wnętrza bloku, ale używaj jej oszczędnie.
Gdy kompilator zgłasza błąd
Błąd z .bar to świetna okazja, żeby nauczyć się czytać komunikaty kompilatora. Dart Sass mówi dokładnie, co się stało, w którym pliku i w której linii:
1Error: Undefined variable.
2 ╷
39 │ color: $local-color; // błąd, $local-color nie jest dostępne tutaj
4 │ ^^^^^^^^^^^^
5 ╵
6 styles.scss 9:10 root stylesheetPierwsza linia opisuje problem, a ostatnia wskazuje plik, numer linii i kolumnę. Z takim komunikatem naprawisz każdy błąd w pięciu krokach:
- Przeczytaj komunikat błędu kompilacji.
- Znajdź wskazany plik i numer linii.
- Sprawdź składnię: brakujący średnik, nawias klamrowy albo literówkę w nazwie zmiennej.
- Popraw kod.
- Skompiluj ponownie i sprawdź wynik w przeglądarce.
Dlaczego to ważne
Zmienne w Sass to jedno z najważniejszych narzędzi do utrzymania spójnego i łatwego w zarządzaniu kodu CSS. Dzięki nim tworzysz bardziej dynamiczne, konfigurowalne arkusze stylów. Moja rada: wszystkie zmienne globalne trzymaj na początku pliku albo w osobnym pliku, a w następnej lekcji zobaczysz, jak wydzielić je do partiala i wczytać dyrektywą @use.
W piaskownicy poniżej zmień wartość jednej zmiennej w pliku main.scss i obserwuj, ile miejsc w wynikowym CSS zmieni się naraz.
Pamiętaj: zmienna to kartusz, czyli jedno imię i jedna wartość, którą kompilator wpisze wszędzie tam, gdzie ją przywołasz.
Kod do tej lekcji: index.html
1<!DOCTYPE html>
2<html lang="pl">
3<head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <title>SCSS - Projekt E-commerce</title>
7 <link rel="stylesheet" href="main.css">
8 <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
9</head>
10<body>
11 <!-- Header -->
12 <header class="header">
13 <div class="header__top">
14 <div class="container">
15 <div class="header__top-info">
16 <span>+48 123 456 789</span>
17 <span>kontakt@shopmaster.pl</span>
18 </div>
19 <div class="header__top-links">
20 <a href="#">O nas</a>
21 <a href="#">Dostawa</a>
22 <a href="#">Pomoc</a>
23 </div>
24 </div>
25 </div>
26
27 <div class="header__main">
28 <div class="container">
29 <a href="#" class="header__logo">ShopMaster</a>
30
31 <div class="header__search">
32 <input type="text" placeholder="Czego szukasz?">
33 <button type="submit">Szukaj</button>
34 </div>
35
36 <div class="header__actions">
37 <a href="#" class="header__actions-item">
38 <span></span>
39 <span>Konto</span>
40 </a>
41 <a href="#" class="header__actions-item">
42 <span></span>
43 <span>Ulubione</span>
44 <span class="badge">3</span>
45 </a>
46 <a href="#" class="header__actions-item">
47 <span></span>
48 <span>Koszyk</span>
49 <span class="badge">5</span>
50 </a>
51 </div>
52 </div>
53 </div>
54
55 <nav class="navigation">
56 <div class="container">
57 <ul class="navigation__menu">
58 <li class="navigation__item">
59 <a href="#" class="navigation__link">Elektronika</a>
60 </li>
61 <li class="navigation__item">
62 <a href="#" class="navigation__link">Moda</a>
63 </li>
64 <li class="navigation__item">
65 <a href="#" class="navigation__link">Dom i ogród</a>
66 </li>
67 <li class="navigation__item">
68 <a href="#" class="navigation__link">Sport</a>
69 </li>
70 <li class="navigation__item navigation__item--sale">
71 <a href="#" class="navigation__link">Wyprzedaż</a>
72 </li>
73 </ul>
74 </div>
75 </nav>
76 </header>
77
78 <!-- Hero Section -->
79 <section class="hero">
80 <div class="hero__content">
81 <h1>Zimowa wyprzedaż do -70%</h1>
82 <p>Odkryj najlepsze oferty na elektronikę, modę i wiele więcej!</p>
83 <div class="btn-group">
84 <a href="#" class="btn btn--primary btn--large">Zobacz oferty</a>
85 <a href="#" class="btn btn--outline btn--large">Dowiedz się więcej</a>
86 </div>
87 </div>
88 </section>
89
90 <!-- Categories Section -->
91 <section class="categories section">
92 <div class="container">
93 <h2 class="section__title">Popularne kategorie</h2>
94 <div class="categories__grid">
95 <a href="#" class="category-card">
96 <div class="category-card__icon">◆</div>
97 <h3 class="category-card__title">Elektronika</h3>
98 <p class="category-card__count">1234 produktów</p>
99 </a>
100 <a href="#" class="category-card">
101 <div class="category-card__icon">◆</div>
102 <h3 class="category-card__title">Moda</h3>
103 <p class="category-card__count">5678 produktów</p>
104 </a>
105 <a href="#" class="category-card">
106 <div class="category-card__icon">◆</div>
107 <h3 class="category-card__title">Dom i ogród</h3>
108 <p class="category-card__count">910 produktów</p>
109 </a>
110 <a href="#" class="category-card">
111 <div class="category-card__icon">◆</div>
112 <h3 class="category-card__title">Sport</h3>
113 <p class="category-card__count">2345 produktów</p>
114 </a>
115 </div>
116 </div>
117 </section>
118
119 <!-- Featured Products -->
120 <section class="products section">
121 <div class="container">
122 <div class="section__header">
123 <h2 class="section__title">Polecane produkty</h2>
124 <a href="#" class="btn btn--ghost">Zobacz wszystkie →</a>
125 </div>
126
127 <div class="products__grid">
128 <!-- Product Card 1 -->
129 <div class="product-card">
130 <div class="product-card__badge product-card__badge--sale">-30%</div>
131 <div class="product-card__image">
132 <img src="https://picsum.photos/300/300?random=10" alt="Product 1">
133 <div class="product-card__overlay">
134 <button class="btn btn--primary btn--small">Szybki podgląd</button>
135 <button class="btn btn--outline btn--small">Lubię</button>
136 </div>
137 </div>
138 <div class="product-card__content">
139 <p class="product-card__category">Elektronika</p>
140 <h3 class="product-card__title">Smartfon XYZ Pro 128GB</h3>
141 <div class="product-card__rating">
142 <span class="product-card__rating-stars">5/5</span>
143 <span class="product-card__rating-count">(125)</span>
144 </div>
145 <div class="product-card__price">
146 <span class="product-card__price-current">1 399 zł</span>
147 <span class="product-card__price-original">1 999 zł</span>
148 <span class="product-card__price-discount">-30%</span>
149 </div>
150 <div class="product-card__actions">
151 <button class="btn btn--primary">Do koszyka</button>
152 </div>
153 </div>
154 </div>
155
156 <!-- Product Card 2 -->
157 <div class="product-card">
158 <div class="product-card__badge product-card__badge--new">Nowość</div>
159 <div class="product-card__image">
160 <img src="https://picsum.photos/300/300?random=11" alt="Product 2">
161 <div class="product-card__overlay">
162 <button class="btn btn--primary btn--small">Szybki podgląd</button>
163 <button class="btn btn--outline btn--small">Lubię</button>
164 </div>
165 </div>
166 <div class="product-card__content">
167 <p class="product-card__category">Audio</p>
168 <h3 class="product-card__title">Słuchawki bezprzewodowe Premium</h3>
169 <div class="product-card__rating">
170 <span class="product-card__rating-stars">4/5</span>
171 <span class="product-card__rating-count">(89)</span>
172 </div>
173 <div class="product-card__price">
174 <span class="product-card__price-current">799 zł</span>
175 </div>
176 <div class="product-card__actions">
177 <button class="btn btn--primary">Do koszyka</button>
178 </div>
179 </div>
180 </div>
181
182 <!-- Product Card 3 -->
183 <div class="product-card">
184 <div class="product-card__image">
185 <img src="https://picsum.photos/300/300?random=12" alt="Product 3">
186 <div class="product-card__overlay">
187 <button class="btn btn--primary btn--small">Szybki podgląd</button>
188 <button class="btn btn--outline btn--small">Lubię</button>
189 </div>
190 </div>
191 <div class="product-card__content">
192 <p class="product-card__category">Gaming</p>
193 <h3 class="product-card__title">Konsola do gier NextGen</h3>
194 <div class="product-card__rating">
195 <span class="product-card__rating-stars">5/5</span>
196 <span class="product-card__rating-count">(234)</span>
197 </div>
198 <div class="product-card__price">
199 <span class="product-card__price-current">2 199 zł</span>
200 </div>
201 <div class="product-card__actions">
202 <button class="btn btn--primary">Do koszyka</button>
203 </div>
204 </div>
205 </div>
206 </div>
207 </div>
208 </section>
209
210 <!-- Newsletter -->
211 <section class="newsletter">
212 <div class="container">
213 <div class="newsletter__content">
214 <h2 class="newsletter__title">Zapisz się do newslettera</h2>
215 <p class="newsletter__description">Otrzymuj najlepsze oferty i bądź na bieżąco z nowościami!</p>
216 <form class="newsletter__form">
217 <input type="email" placeholder="Twój adres e-mail" class="newsletter__input">
218 <button type="submit" class="btn btn--primary">Zapisz się</button>
219 </form>
220 </div>
221 </div>
222 </section>
223
224 <!-- Footer -->
225 <footer class="footer">
226 <div class="container">
227 <div class="footer__grid">
228 <div class="footer__column">
229 <h3 class="footer__title">O nas</h3>
230 <ul class="footer__list">
231 <li><a href="#">Kim jesteśmy</a></li>
232 <li><a href="#">Kariera</a></li>
233 <li><a href="#">Kontakt</a></li>
234 <li><a href="#">Blog</a></li>
235 </ul>
236 </div>
237 <div class="footer__column">
238 <h3 class="footer__title">Pomoc</h3>
239 <ul class="footer__list">
240 <li><a href="#">Centrum pomocy</a></li>
241 <li><a href="#">Dostawa i płatności</a></li>
242 <li><a href="#">Zwroty i reklamacje</a></li>
243 <li><a href="#">FAQ</a></li>
244 </ul>
245 </div>
246 </div>
247 <div class="footer__bottom">
248 <p>© 2024 ShopMaster. Wszystkie prawa zastrzeżone.</p>
249 </div>
250 </div>
251 </footer>
252</body>
253</html>Widzisz błąd w tej lekcji?
Zadania praktyczne w grze
- Układanie w pionie
Ułóż kroki debugowania błędu kompilacji SASS: