Kurs HTML i CSS · Moduł 7: SASS
Mapy i listy w Sass
W tej lekcji5
Wyobraź sobie że Twoja świątynia potrzebuje pięciu rozmiarów tekstu, czterech kolorów i czterech progów responsywności. Z samymi zmiennymi skończysz z tuzinem luźnych deklaracji w rodzaju $size-1 i $color-primary, a każdą klasę pomocniczą napiszesz ręcznie. Sass oferuje dwie struktury danych, które porządkują takie wartości: listy i mapy. Wyobraź je sobie jak katalogi skarbów w egipskiej świątyni: listy to uporządkowane spisy, a mapy to katalogi z opisami.
Listy w Sass
Lista to kolekcja wartości oddzielonych spacjami lub przecinkami, jak papirus z wykazem imion faraonów. Poniżej zobaczysz oba rodzaje separatorów i pierwszą pętlę, która przechodzi po liście dyrektywą @each:
1// Lista oddzielona spacjami
2$spacing: 4px 8px 16px;
3
4// Lista oddzielona przecinkami (nazwy czcionek)
5$font-stack: Helvetica, Arial, sans-serif;
6
7// Lista oddzielona przecinkami
8$sizes: 12px, 14px, 16px, 18px, 24px;
9
10// Iteracja po liście z @each
11@each $size in $sizes {
12 .text-#{$size} {
13 font-size: $size;
14 }
15}Pętla @each bierze po kolei każdy element listy $sizes i generuje dla niego klasę, więc po kompilacji dostaniesz reguły od .text-12px do .text-24px. Zapis #{$size} to interpolacja, która wstawia wartość zmiennej do nazwy selektora. Lista $spacing z odstępami rozdzielonymi spacjami działa dokładnie tak samo, różni się tylko separator.
Do pracy z listami służą wbudowane funkcje:
length($lista)- zwraca liczbę elementównth($lista, $index)- zwraca element o podanym indeksie (indeks zaczyna się od 1)append($lista, $wartość)- dodaje element na koniecjoin($lista1, $lista2)- łączy dwie listy
Pobierzmy teraz drugi element listy kolorów funkcją nth():
1$colors: red, blue, green;
2
3.element {
4 color: nth($colors, 2); // blue
5}Indeks 2 wskazuje blue, bo w Sass liczymy od jedynki, a nie od zera jak w JavaScripcie. Pamiętaj też, że listy w Sass są niezmienne: append() i join() nie modyfikują oryginału, tylko zwracają nową listę, którą trzeba zapisać do zmiennej.
Mapy w Sass
Mapa to zbiór par klucz-wartość, niczym tajemny katalog egipskich artefaktów, w którym każdy przedmiot ma swoją etykietę. Definiujemy ją w nawiasach okrągłych, a pary oddzielamy przecinkami:
1$breakpoints: (
2 "mobile": 320px,
3 "tablet": 768px,
4 "desktop": 1024px,
5 "wide": 1440px
6);
7
8$colors: (
9 "primary": #2C3E50,
10 "secondary": #D4AF37,
11 "accent": #E74C3C,
12 "background": #F5F0E1
13);Klucze w cudzysłowie to nazwy, a po dwukropku stoją wartości. Sama definicja, tak jak zwykła zmienna, nie generuje żadnego CSS.
Aby pobrać wartość z mapy, używamy funkcji map-get(), która przyjmuje mapę i klucz:
1.header {
2 background-color: map-get($colors, "primary");
3 color: map-get($colors, "secondary");
4}Nagłówek dostanie tło #2C3E50 i złoty tekst #D4AF37. Klucz możesz zapisać w cudzysłowie pojedynczym lub podwójnym, bo Sass traktuje oba tak samo. Uważaj za to na literówki: dla nieistniejącego klucza map-get() zwraca null, a deklaracja z taką wartością po prostu znika z CSS, bez żadnego błędu.
W nowych projektach spotkasz też zapis modułowy: po dodaniu na początku pliku @use "sass:map" piszesz map.get($colors, "primary"). Działa identycznie, a globalne funkcje w rodzaju map-get() są w nowszych wersjach Dart Sass oznaczone jako przestarzałe. Polecam Ci zapis modułowy choć starszy wciąż jest wszędzie w dokumentacji i starszym kodzie.
Iteracja po mapach z @each
Prawdziwa siła map ujawnia się w pętli. Dyrektywa @each może pobierać jednocześnie klucz i wartość, więc możemy automatycznie wygenerować klasy na podstawie mapy:
1@each $name, $color in $colors {
2 .text-#{$name} {
3 color: $color;
4 }
5 .bg-#{$name} {
6 background-color: $color;
7 }
8}Po kompilacji otrzymamy klasy .text-primary, .text-secondary, .bg-primary itd. Dodanie nowego koloru do mapy wystarczy, by pętla sama dopisała dla niego obie klasy.
Mapy dla breakpointów
Jednym z najczęstszych zastosowań map jest przechowywanie breakpointów i używanie ich w media queries. Poniższy mixin pobiera szerokość z mapy, a dyrektywa @content wstawia w media query blok przekazany przy @include:
1$breakpoints: (
2 "sm": 576px,
3 "md": 768px,
4 "lg": 1024px,
5 "xl": 1200px
6);
7
8@mixin respond-to($breakpoint) {
9 $value: map-get($breakpoints, $breakpoint);
10 @media (min-width: $value) {
11 @content;
12 }
13}
14
15.container {
16 width: 100%;
17
18 @include respond-to("md") {
19 width: 750px;
20 }
21
22 @include respond-to("lg") {
23 width: 970px;
24 }
25}Kompilator zamieni każde wywołanie na zwykłe media query, na przykład @media (min-width: 768px) z szerokością 750px dla .container. Progi zmieniasz odtąd w jednym miejscu, a nazwy w rodzaju "md" czyta się łatwiej niż surowe piksele.
Przydatne funkcje dla map
map-get($mapa, $klucz)- pobiera wartośćmap-has-key($mapa, $klucz)- sprawdza, czy klucz istniejemap-keys($mapa)- zwraca listę kluczymap-values($mapa)- zwraca listę wartościmap-merge($mapa1, $mapa2)- łączy dwie mapy
Mapy i listy to narzędzia organizacji kodu na wyższym poziomie. Pozwalają przechowywać konfigurację w jednym miejscu i generować style automatycznie, jak sprawny system zarządzania zasobami w starożytnej świątyni. Spróbuj dodać do mapy $colors turkus i skompilować arkusz, a pętla sama utworzy klasy .text-turquoise i .bg-turquoise.
Pamiętaj: lista to spis skarbów, a mapa to katalog z etykietami, z którego map-get() wydaje dokładnie ten przedmiot, o który poprosisz.
Kod do tej lekcji: index.html
1<!DOCTYPE html>
2<html lang="pl">
3<head><title>Formularze HTML</title></head>
4<body style="background:#d4a574;font-family:serif;padding:20px;color:#3d2914">
5<h1>Formularze HTML</h1>
6<form><label>Imię pisarza: <input type="text"></label></form>
7</body>
8</html>Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. Jak pobrać wartość z mapy SASS o nazwie $colors dla klucza 'primary'?