SVG za dizajnere 🤜🤛️ developere

SVG nije novost u 2019. godini i tokom par godina je standard mnogo napredovao. Tako smo i dobili različite načine da koristimo SVG unutar HTML-a i CSS-a.

Proći ću kroz jedan konkretan i stabilan način za korišćenje SVG-a unutar HTML-a, tačnije kako napraviti sistem ikonica pomoću SVG-a. Debeda da li koristiti SVG ili font za ikonice je već mnogo puta vođena i moj savet je da koristite SVG. Ovaj članak obuhvata i dizajnere zato što su oni dužni da urade samu pripremu SVG-a.

Priprema

Kao i kod štampe, pre korišćenja vektorske slike, potrebno je uraditi grafičku pripremu. Iako je najlakše samo izvesti ikonicu iz našeg omiljenog alata (Illustrator, Sketch, Inscape itd.), uz malo truda, možemo mnogo olakšati developerima i sprečiti razne probleme na koje oni mogu naići.

illustrator (levo), Sketch (desno)

Svaka ikonica za sebe

Prilikom pravljenja ikonice, svaka ikonica treba da ima svoj zaseban "artboard" tj. radnu površinu. Ovim se osiguravamo da ikonica sadrži tačno ono što joj je potrebno i nema sakrivenih putanja u pozadini.

Oblik je bitan

Oblik same ikonice nije bitan. Ono što jeste bitno je da "artboard" u kome se nalazi ikonica bude kvadratnog oblika. Kada se ikonica nalazi u kvadratnoj radnoj površini to dosta olakšava rad sa ikonicom, jer možemo biti sigurni da su sve ikonice jednake visine i širine.

Primer SVG ikonica (svgicons)

Tačne dimenzije radne površine nisu definisane, ali postoji nepisano pravilo da to bude 16x16 ili 20x20 piksela zato što se ikonice najčešće koriste u toj izvornoj veličini.

Prostor da diše

Ovo je možda i najčešća greška kod dizajnera, a to je da se ikonica prostire od ivice do ivice "artboarda".

Kada veb pregledač prikazuje SVG ikonicu on koristi "anti-aliasing", ali često taj jedan dodatni piksel koji doda AA neće da se prikaže van našeg viewBoxa.

Ovaj problem je dosta vidljiv u Firefox i Edge pregledačima i, kada se javi, to izgleda ovako:

IcoMoon SVG ikonice na Firefoxu

Kako bismo izbegli ovaj problem, pridržavajte se pravila da ikonica ima 0.5px ili 1px prostora sa svake strane.


Izvoz ikonice

Kada smo napravili novu radnu površinu, a zatim napravili našu ikonicu i umanjili je za jedan piksel kao što je gore rečeno, tek tada smo spremni da izvezemo ikonicu iz našeg omiljenog alata. Ovaj proces će zavisiti od alata do alata, ja ću konkretno pokriti dva najkorišćenija alata, Sketch i Illustrator.

Sketch

Prilikom izvoza iz Sketch-a može doći do poznatog problema da Sketch ubaci nepotreban markup koji će da nam poveća veličinu datoteke. Osim same veličine datoteke ovakav markup može da napravim problem prilikom korišćenja ikonice.

Evo kako izgleda loša ikonica iz Sketch-a:

<?xml version="1.0" encoding="UTF-8"?>
<svg width="100px" height="94px" viewBox="0 0 100 94" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <!-- Generator: Sketch 54.1 (76490) - https://sketchapp.com -->
    <title>logo-m</title>
    <desc>Created with Sketch.</desc>
    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="Artboard" transform="translate(0.000000, -3.000000)" fill="#1A1A1A" fill-rule="nonzero">
            <g id="logo-m" transform="translate(0.000000, 3.000000)">
                <path d="..." id="Shape"></path>
            </g>
        </g>
    </g>
</svg>

Možemo primetiti da postoji veliki broj grupa <g> i ono što često pravi problem je  transform koji ustvari ničemu ne služi. Ako pogledamo malo bliže, videćemo da jedan drugog poništavaju. Ovaj primer zna biti mnogo lošiji, sa mnogo više grupa.

Zašto se ovo tačno dešava ne mogu reći sa sigurnošću, ali sam zaključio da se dešava kada izvozimo "shape" a ne "artboard", što bismo svakako trebali da radimo.

Pravi način da izvezemo ikonicu je da izaberemo "artboard" a zatim opciju "Make Exportable", dok za format izaberemo "SVG".

Ikonice koje Sketch izveze nisu optimizovane. Videćemo kasnije kako da ih optimizujemo.

Illustrator

U Illustrator-u je ovaj proces dosta jednostavniji i Illustrator nema probleme sa grupama i transformacijama. Idemo na File > Export > Export As... i jedina bitna stvar je da izaberemo u dnu "Use Artboards".

Ikonice koje Illustrator izveze su optimizovane. Moguće je optimizovati ih dalje ali ima minimalnih dobitka.
Kad izvozimo u bilo kom alatu, bitno je da naglasimo da izvozimo "artboard" a ne samo ikonicu. Zato što ako se setimo onog pravila da umanjimo ikonicu za par piksela, to više neće važiti ako izvezemo samo ikonicu. Zato moramo da izvezemo ceo "artboard" koji u sebi ima ikonicu manju za par piksela.

Optimizacija SVGa

Kad smo uspešno izvezli ikonice vreme je da dodatno sačuvamo prostor tako što ih optimizujemo.

SVG datoteke obično sadrže dosta redundantnih i beskorisnih informacija. Često su to metapodaci, komentari, skriveni elementi i druge stvari koje se mogu sigurno ukloniti ili pretvoriti bez uticaja na rezultat SVG-a.

Trenutni zlatni standard je SVGO koji je konkretno NodeJS alat, ali dolazi u različitim oblicima.

Komandna linija:

Unutar foldera gde su nam ikonice pokrenemo svgo *.svg i ovo će nam optimizovati sve ikonice.

Ostali alati:

Uklanjanje boje

Ikonica u sebi ne bi trebala da ima definisanu boju. Ako ikonica ima "hardkodiranu" boju unutar sebe, nećemo moći da izmenimo boju ikonice preko CSS-a, što znači da gubimo kontrolu nad bojama. Zato je uvek dobro da sklonimo boje.

Postoje dva načina da se dodeli boja u SVG-u:

  • Preko atributa fill.
  • Preko CSS-a koji je unutar SVG-a ( style blok).

Bitno je da naš SVG ne sadrži ni jedan fill atribut, niti style blok.

Illustrator ne dodaje fill attribut putanjama koje su pune crne boje (#000000). Zato se generalno preporučuju da ikonice budu potpuno crne. Za sketch ovo ne važi, već moramo ručno obrisati.

Sistem ikonica

Krećemo u developerski deo posla. Ako niste developer ili jednostavno niste zainteresovani šta sve developeri treba da urade da bi prikazali ikonice na sajtu, ovaj deo nije za vas.

Sistem ikonica pravimo pomoću "sprajta" (ne to nije sok). Sprajt je jedna velika slika koja sadrži sve moguće sličice tako da se znaju kordinate svake sličice i na taj način se vrši mapiranje. Ova tehnika postoji još od 70ih godina, kada je Atari, jedan od prvih, implementirao ovo.

Sprajt za Pac-Man (Atari 7800)

Malo preciznija i slobodnija definicija u našem slučaju bi bila mapa simbola, zato što je mapa ustvari jedan SVG koji ima definisane simbole.

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
  <path d="M16.5 18.8c-.1-.8-1-.9-1.5-.8-.5-2 1.3-5 1.4-5.8.1-.8-.5-5.2-.6-7.5-.1-2.3-3.4-4.9-4-4.5-.6.6.8 1.4.1 2.2-.7.7-.9 1.2-1.4 1.9-1.3 2 2.3 2 2.3 2S10 8.5 9.4 9.5c-.6 1-.8 2-1.5 2.9-1.6 2.1-1.2 5.7-1.2 5.7s-3-1-1.3-4.4c1.2-2.6 1.9-6.4-.9-5.4-1.2.4.1 1.2.3 1.5.8.9.1 2.3-.3 3.1-1.2 2.2-1.7 4.6.9 6 1.2.6 2.7.8 4.3.8h4c1.3.1 2.8-.1 2.8-.9z"/>
</svg>

To izgleda ovako:

Dodavanje ikonice na mapu

Vrlo je jednostavno dodati ikonice na mapu, kao što sam rekao, SVG mapa je SVG sa simbolima.

<svg xmlns="http://www.w3.org/2000/svg">
  <symbol id="macka" viewBox="0 0 20 20">
    <path d="M16.5 18.8c-.1-.8-1-.9-1.5-.8-.5-2 1.3-5 1.4-5.8.1-.8-.5-5.2-.6-7.5-.1-2.3-3.4-4.9-4-4.5-.6.6.8 1.4.1 2.2-.7.7-.9 1.2-1.4 1.9-1.3 2 2.3 2 2.3 2S10 8.5 9.4 9.5c-.6 1-.8 2-1.5 2.9-1.6 2.1-1.2 5.7-1.2 5.7s-3-1-1.3-4.4c1.2-2.6 1.9-6.4-.9-5.4-1.2.4.1 1.2.3 1.5.8.9.1 2.3-.3 3.1-1.2 2.2-1.7 4.6.9 6 1.2.6 2.7.8 4.3.8h4c1.3.1 2.8-.1 2.8-.9z"/>
  </symbol>
</svg>

Možda izgleda kao da se svašta desilo, ali je ustvari prilično jednostavno. Samo treba da prebacimo <svg viewBox="..."> u <symbol id="..." viewBox="...">.

Ovim smo SVG ikonicu prebacili u simbol i dodelili mu jedinstven selektor (id). Ovo treba uraditi za svaku ikonicu. Kako to može biti mukotrpan proces, postoje alati za koji to mogu uraditi umesto nas.

Upotreba ikonice

Ikonice se dodaju pomoću <use> elementa, ali postoje dva načina da referenciramo sprajt:

  • Interni sprajt
  • Eksterni sprajt

Eksterni sprajt

Kao što ime kaže, sprajt se nalazi u eksternoj datoteci, recimo ikonice.svg

<svg>
  <use xlink:href="/putanja/do/ikonice.svg#macka"></use>
</svg>

Ovim smo uzeli ikonice.svg i iz tog SVG-a i uzeli simbol sa ID-em macka. Ovaj pristup zahteva jedan dodatni HTTP zahtev da pribavi taj fajl. Obično taj fajl nije toliko veliki pa zato preporučujem interni sprajt.

Interni sprajt

Umesto da idemo po fajl, možemo staviti SVG sa simbolima negde na početku stranice, a zatim da koristimo ikonice iz istog.


<!DOCTYPE html>
<html>
<head>
    <title>Nas sajt</title>
</head>
<body>
    <!-- Nas interni sprajt sa ikonicama -->
    <svg style="display: none">
        <symbol id="macka" viewbox="0 0 20 20">
            <path d="M16.5 18.8c-.1-.8-1-.9-1.5-.8-.5-2 1.3-5 1.4-5.8.1-.8-.5-5.2-.6-7.5-.1-2.3-3.4-4.9-4-4.5-.6.6.8 1.4.1 2.2-.7.7-.9 1.2-1.4 1.9-1.3 2 2.3 2 2.3 2S10 8.5 9.4 9.5c-.6 1-.8 2-1.5 2.9-1.6 2.1-1.2 5.7-1.2 5.7s-3-1-1.3-4.4c1.2-2.6 1.9-6.4-.9-5.4-1.2.4.1 1.2.3 1.5.8.9.1 2.3-.3 3.1-1.2 2.2-1.7 4.6.9 6 1.2.6 2.7.8 4.3.8h4c1.3.1 2.8-.1 2.8-.9z" />
        </symbol>
    </svg>
    <!-- Ovde neki HTML -->
    <svg><use xlink:href="#macka"></use></svg>
</body>
</html>

Razlike

Osim što je drugačiji stil pisanja, postoji velika razlika između ova dva načina. Jedna od glavnih je podrška pregledača:

Chrome Edge Firefox IE Opera Safari
Eksterni sprajt 36 Ne 15 Ne 23 7.1
Interni sprajt 36 9 15 12 23 7.1

Više na Can I Use.

Imajte na umu da interni sprajt nije moguće keširati, dok će se eksterni sprajt keširati od strane pregledača.

Ako baš želimo da koristimo eksterni sprajt i IE možemo da uključimo svg4everybody "polifil".

Stilizovanje ikonica CSS-om

Sad kad smo dodali SVG ikonice i naučili različite načine kako da ih uključimo u HTML, vreme je da pređemo na CSS. SVG ikonice koje su deo mape možemo posebno da stilizujemo kao da su ustvari posebno uključene i tu leži sama moć mape, mogućnosti internog SVG-a bez ponavljanja.

.icon {
    fill: dodgerBlue;
    height: 30px;
}

Ako dodamo klasu .icon na našu ikonicu <svg class="icon"><use xlink:href="#macka"></use></svg> dobijamo sledeći razultat.

Kako stalno ne bismo pisali fill , height i duplirali kod za color ovo može lepše da se standardizuje.

.icon {
    fill: currentColor;
    width: 1em;
    height: 1em;
    vertical-align: middle;
    overflow: hidden;
}

Ovim će se naša ikonica ponašati kao i font.

Macka
Macka