Zaawansowany SASS- funkcje, pętle i logika – studium przypadku.

Używasz SASS’a w codziennej pracy? Pewnie dobrze znasz jego dobre strony ale czy napewno wykorzystujesz jego pełny potencjał? Nawet jeśli nie znasz jeszcze wszystkich zagadnień związanych z tym narzędziem to po lekturze tego artykułu wiele spraw zwyczajnie się wyjaśni.

Czego się dzisiaj dowiesz?

SASS to pre-procesor CSS i jeśli czytałeś/aś moje poprzednie wpisy z tej serii to już to wiesz. Dzisiaj opiszę bardziej zaawansowane opcje tzn. string interpolation, funkcje, pętle i operator logiczny if. Kolejna porcja praktycznej wiedzy.

Seria SASS

W skład serii wchodzą:

  1. Podstawy SASS – struktura kodu, importy, zmienne, mixiny i extendy.
  2. RWD i CSS Math. Jak sobie z tym poradzić? Mobile First vs Desktop First.
  3. Zaawansowany SASS – funkcje, pętle i logika.

Zaawansowany SASS

A więc bez rozbudowanych wstępów (które możesz poczytać w poprzednich częściach serii) przejdę do poszczególnych metod.

String interpolation

Ten temat poruszyłem już w artykule o RWD. W skrócie chodzi o to, że możemy modyfikować np. nazwy selektorów CSS poprzez dodanie wartości zdefiniowanej w zmiennej. Fragment kodu to opisujący wyglada np. tak:

$house-number: 5;

.house-#{$house-number} {
    width: 50%;
}

Do selektora ‘.house-‘ dodajemy wartość zmiennej $house-number i otrzymujemy ‘.house-5’.

String interpolation + Mixin & Extend

Aby lepiej zrozumieć co się dzieje poniżej warto sprawdzić mój wpis na temat podstaw SASS

Teraz wykorzystam tą właściwość w ciekawy sposób. Załóżmy, że mamy do stworzenia na stronie 4 buttony. Mają być generalnie takie same poza… kolorem w tle… powiedzmy, ża tła mają być w kolorach białym, czerwonym, zielonym i niebieskim. Spróbuje napisać to w SASS’ie w sposób który zminimalizuje ilość potrzebnego kodu…

Zacznijmy od HTML:

<div class="container">
        <button class="button-red">Click</button>
        <button class="button-white">Click</button>
        <button class="button-green">Click</button>
        <button class="button-blue">Click</button>
</div>

Potem zdefiniujmy Extenda w którym zdefiniuje reguły powtarzające się dla każdego buttona:

%button-basic {
    max-width: 150px;
    padding: 10px 50px;
    border: none;
    cursor: pointer;
    &:focus {
        outline: none;
    }
}

Czas na Mixin w którym użyjemy string interpolation modyfikując selektor CSS dla każdego buttona. Zrobię to przy pomocy parametru podanego do mixina:

@mixin button($color) {
    // String interpolation
    .button-#{$color} {
        @extend %button-basic;
        background-color: $color;
        &:hover {
            background-color: darken($color: $color, $amount: 10);
        }
    }
}

Ostatnim krokiem jest wywołanie zdefiniowanych reguł w odpowiednim miejscu w naszym kodzie:

.container {
    @include button(red);
    @include button(green);
    @include button(white);
    @include button(blue);
}

Jak nie trudno zauważyć wykorzystując tą metodę trzeba mieć na uwadze nazewnictwo klas w HTML. Musi to być spójne… A teraz czas na działający przykład:

See the Pen string_inter by Bart (@bedekodzic) on CodePen.

Dla ciekawskich, tak powyższy .scss został przekonwertowany na .css:

.container .button-red, .container .button-green, .container .button-white, .container .button-blue {
    max-width: 150px;
    padding: 10px 50px;
    border: none;
    cursor: pointer; }

.container .button-red:focus, .container .button-green:focus, .container .button-white:focus, .container .button-blue:focus {
    outline: none; }

.container .button-red {
    background-color: red; }
.container .button-red:hover {
    background-color: #cc0000; }

.container .button-green {
    background-color: green; }
.container .button-green:hover {
    background-color: #004d00; }

.container .button-white {
    background-color: white; }
.container .button-white:hover {
    background-color: #e6e6e6; }

.container .button-blue {
    background-color: blue; }
.container .button-blue:hover {
    background-color: #0000cc; }

Funkcje w CSS

Teraz mechanizm który na pierwszy rzut oka jest podobny do mixina:

@function adjust-font($height-1, $height-2) {
    @return $height-1/$height-2;
}

Różnica polega na tym, że funkcja zwraca jakąś konkretną wartość po wykonaniu zdefiniowanych obliczeń. Następnie tą wartość można przyporządkować do odpowiedniej reguły CSS, w przykładzie określam rozmiar czcionki na podstawie proporcji dwóch wartości (np. wysokość jakiegoś kontenera):

$cont-1-height: 100px;
$cont-2-height: 170px;

h1 {
    font-size: #{adjust-font($cont-1-height, $cont-2-height)}em;
}

Ciekawe, co nie?

Logika czyli operator @if

Skoro w SASS możemy pisać funkcje jak w pełnoprawnym języku programowania to dlaczego by nie wprowadzić operatorów logicznych?

Pozwala to na zwiększenie możliwości funkcji:

$cont-1-height: 100px;
$cont-2-height: 170px;

@function adjust-font($height-1, $height-2) {
    @if ($height-1/$height-2) < 1 {
        @return 2;
    }
    @else {
        @return 3;
    }
}

.container {
    h1 {
        font-size: #{adjust-font($cont-1-height, $cont-2-height)}em;
    }
}

Intrygujące…

Pętla @for

No to wejdźmy dalej w możliwości logiczne SASS’a. Podobnie jak pętle for w innych językach programowania tak i tutaj możemy “iterować” przez dane. Aby nabrało trochę praktycznego sensu przeanalizujmy taki przykład:

<div class="container">
    <div class="element-1"></div>
    <div class="element-2"></div>
    <div class="element-3"></div>
    <div class="element-4"></div>
    <div class="element-5"></div>
    <div class="element-6"></div>
</div>

Na każdym z tych divów chcemy utworzyć tło za pomocą CSS używając właściwość background-image. Wiemy, że możemy iterować w CSS za pomocą @for jednak aby osiągnąć to co chcemy w “sprytny” sposób potrzebujemy przyjąć konwencję nazewnictwa w naszych plikach graficznych:

element-1 = image-1.png

element-2 = image-2.png

Jeśli numer przy pliku odpowiada numerowi klasy to jesteśmy w domu 🙂 W takim razie zdefiniujmy style:

%image-div {
    height: 150px;
    width: 150px;
    background-position: center;
    background-size: cover;
    background-repeat: no-repeat;
}

.container {
    @for $i from 1 to 7 {
        .element-#{$i} {
            @extend %image-div;
            background-image: url('../image-#{$i}.png');
        }
    }
}

Voila 🙂

Listy

Ostatnia sprawa w dzisiejszym wpisie. Czym jest lista? Jest bardziej zaawansowana forma pętli @for albo inaczej, bardziej wyewoluowana. Dlaczego?

Otóż pętla @for pozwala nam przemieszczać się po selektorach używając tylko liczb naturalnych zdefiniowanych np. jako $i (w przykładzie powyżej liczby od 1 do 6). Lista pozwala nam iterować po… nazwach 🙂

Przypomina to trochę mechanizm tablic w JavaScript. Załóżmy, że najpierw tworzymy tablicę z 7 elementami:

$table: ".head-1" h2 "#head-3" h4 h5 h6 ".paragraph";

W tablicy możemy wybrać element po tagu HTML, klasie lub id jednak wiemy już, że najlepszą praktyką jest wybieranie klas.

Następnie iteruje się przez każdy element na liście używając pętli @each $item in $list:

$table: ".head-1" h2 "#head-3" h4 h5 h6 ".paragraph";

@each $text in $table {
    #{$text} {
        font-size: 1em;
    }
}

Na każdym z elementów ustawimy rozmiar czcionki no ale ktoś może powiedzieć, przecież to trochę bez sensu… Racja dlatego możemy dodać np. index w liście który doda nieco elastyczności:

$table: ".head-1" h2 "#head-3" h4 h5 h6 ".paragraph";

@each $text in $table {
    $i: index($table, $text);
    #{$text} {
        font-size: 1em + (1/$i);
    }
}

W ten sposób np. każdy kolejny rozmiar czcionki jest mniejszy. Do równania można dodać również inne zmienne jeśli jest taka potrzeba.

Zaawansowany SASS- co dalej?

Jak zapewne widzicie SASS posiada w sobie wiele bajerów które mogą wzbogacić nasz warsztat. Po chwili refleksji przychodzi przychodzi jednak pytanie: Po co komu w sumie ta cała logika?

Niektóre mechanizmy SASS’a są naprawdę krokiem milowym przy pisaniu CSS jednak czy potrzebujemy tych wszystkich “bajerów” w codziennej pracy? Jak często np. iteracja przez listę może być użyteczna? Czy często mamy do czynienia z jakimś dynamicznym kontentem w CSS?

SASS – podsumowanie

To był ostatni z wpisów ściśle związanych z SASS’em. Opisałem w nich sporo właściwości tego pre-procesora mając nadzieję, że wyczerpałem temat w dużym stopniu. Niektóre z nich są bardziej użyteczne a niektóre mniej ale warto znać je wszystkie 🙂

Drogi czytelniku jeśli doszukałeś się w tym wpisie błędów logicznych lub nieścisłości to napisz proszę w komentarzu 🙂 A może po prostu zapomniałem o czymś ciekawym?


Bartek Cis

Piszę dla was tego bloga bo lubię aplikacje internetowe. Mogę je projektować, kodować a potem o nich pisać czując dreszczyk ekscytacji za każdym razem gdy trafię na coś nowego. Bo uczymy się całe życie. Prawda?