SVG responsivní a stylovatelné

SVG (Scalable Vector Grafic) je otevřený formát pro vektorovou grafiku, podporovaný všemi soudobými prohlížeči. Skvělé na něm je, že můžete grafické prvky libovolně zvětšovat, aniž by byly zubaté, stylovat přes CSS a ve většině případů budou datově menší, než kdyby to byl gif nebo jpeg.

Potud teorie. Jestli máte pocit, že můžete bitmapové grafické prvky lusknutím prstu vyměnit za SVG, mýlíte se. Je to totiž, slovy klasika, past vedle pasti. Takže se podíváme, jak do toho nešlápnout.

SVG samotné

První stupeň tortury je příprava samotné SVG grafiky. SVG je totiž formát velice bohatý a lze v něm dělat spoustu věcí. To ve výsledku znamená, že stejně vypadající výsledek může být dosažen mnoha způsoby a ne všechny pak budou dělat to, co chcete. Když děláte bitmapu, můžete si do Photoshopu (nebo co používáte) napráskat co chcete a pokud to vypadá, jak má, je to v pořádku.

SVG je ale něco docela jiného. Je to vlastně záznam všeho, co jste udělali. Je tedy třeba dávat si pozor na to co děláte a udělat to co možná nejjednodušeji. Je to ve vašem zájmu, zdrojový kód SVG totiž budete muset s velkou pravděpodobností ručně upravovat.

Pro práci s SVG používám Inkscape (skvělý nástroj, zadarmo – no nekupte to), který nabízí spoustu užitečných vlastností, které ale nejsou úplně v souladu se specifikací SVG (tuším třeba vrstvy jsou ten případ) a proto si je ukládá jako vlastní tagy. Ničemu to nevadí, obrázek se zobrazí a vy můžete pracovat s vrstvami. Jen je soubor trochu větší. Ukažme si to na příkladu jednoduché šipečky:
SVG šipečka

Toto je šipečka uložená Inkscapem, má 2 345 bajtů (opravdu). Všimněte si, že šipečka má pevný rozměr, neroztáhne se na celou šířku obrázku.

Zdrojový kód navíc obsahuje mnoho věcí, co pro zobrazení k ničemu nepotřebujete. V tomhle formátu si soubor schovejte pro další úpravy a práci s ním. Pro použití na webu ale zvolte formát Plain SVG a ještě to raději prožeňte optimalizátorem (o obojím si povíme později).

A teď se podíváme, jak vypadá zdrojový kód:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   version="1.1"
   width="100%"
   height="100%"
   id="svg2"
   inkscape:version="0.48.5 r10040"
   sodipodi:docname="bullet-left.svg">
  <metadata
     id="metadata12">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title></dc:title>
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <defs
     id="defs10" />
  <sodipodi:namedview
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1"
     objecttolerance="10"
     gridtolerance="10"
     guidetolerance="10"
     inkscape:pageopacity="0"
     inkscape:pageshadow="2"
     inkscape:window-width="1280"
     inkscape:window-height="962"
     id="namedview8"
     showgrid="false"
     inkscape:zoom="0.22425739"
     inkscape:cx="372.04724"
     inkscape:cy="526.18109"
     inkscape:window-x="-8"
     inkscape:window-y="-8"
     inkscape:window-maximized="1"
     inkscape:current-layer="svg2" />
  <g
     id="g2990">
    <path
       d="M 7.238143,2.8978273 C 11.523124,6.6471854 25.651979,13.668184 33.888986,14.927621 25.651979,16.201534 11.5376,23.309391 7.238143,27.102177 5.718133,22.657958 3.0689726,18.691455 0,14.927621 3.0689726,11.207215 5.718133,7.2986182 7.238143,2.8978273 z m 0.014476,-2.8952572 0,0 0,0 C 7.3105244,-0.15666904 4.8785084,7.0959502 0.01447629,12.032364 2.9821149,9.2529169 5.2838444,5.0113651 7.440811,0.98695755 7.7303367,1.7252481 20.527374,11.482265 29.936959,12.032364 21.699953,10.772927 11.5376,3.7519282 7.2526193,0.0025701 z m 0,29.9948649 C 7.3105244,30.156674 4.8785084,22.846149 0.01447629,17.851831 2.9821149,20.66023 5.2838444,24.945211 7.440811,29.013047 7.7303367,28.274757 20.527374,18.416406 29.936959,17.851831 21.699953,19.125744 11.5376,26.219124 7.2526193,29.997435 z"
       id="path6"
       inkscape:connector-curvature="0" />
  </g>
</svg>

Žádná slast, co? Naštěstí Inkscape umí výsledek vaší práce uložit i jako Plain SVG, což znamená, že do něj neukládá svoje vlastní data, ale jen to, co do SVG patří (víceméně). Je to menší a čitelnější, ale daleko nejlepšího výsledku dosáhnete, když SVG vezmete a proženete optimalizátorem.

Jako nejlepší nastavení se jeví možnost „Extreme“ s tím, že necháme bílé znaky (odškrtnout „Remove whitespace“) a nejméně dvě desetiná místa u atributů a stylů. Pokud máte v obrázku gradienty, odškrtněte také „Remove IDs“. Tato volba by vám totiž gradienty odstranila. Výsledek je následující:

SVG šipečkaVšimněte si, že ani teď se obrázek neroztahuje. Dokud do něj ručně nezasáhneme, ani se roztahovat nebude. O co nám tady šlo bylo odstranění zbytečného balastu. Soubor je teď menší, má pouhých 559 bajtů (tedy asi 24% originálu) a i zdrojový kód vypadá trošičku čitelněji:

<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="100" height="100">
  <path d="M7.24 2.9C11.52 6.65 25.65 13.67 33.89 14.93 25.65 16.2 11.54 23.31 7.24 27.1 5.72 22.66 3.07 18.69 0 14.93 3.07 11.21 5.72 7.3 7.24 2.9zm0.01-2.9 0 0 0 0C7.31-0.16 4.88 7.1 0.01 12.03 2.98 9.25 5.28 5.01 7.44 0.99 7.73 1.73 20.53 11.48 29.94 12.03 21.7 10.77 11.54 3.75 7.25 0zm0 29.99C7.31 30.16 4.88 22.85 0.01 17.85 2.98 20.66 5.28 24.95 7.44 29.01 7.73 28.27 20.53 18.42 29.94 17.85 21.7 19.13 11.54 26.22 7.25 30z"/>
</svg>

A protože už máme kódu méně, můžeme ho začít upravovat.

Upravujeme SVG

Pokud chceme, aby se nám obrázek roztahoval podle velikosti kontejneru, musíme mu nastavit nějaké rozměry, aby prohlížeš věděl, s čím má pracovat. Nejedná se ale o width a height, jak to vidíte v předchozím příkladu. To je jen obal. Je potřeba nastavit parametr  viewBox.

Parametr viewBox obahuje 4 čísla oddělená mezerou. První je dvě jsou odsazení na ose X a Y, druhé dvě šířka a výška.
SVG šipečkaA je to! Šipečka se roztahuje podle velikosti kontejneru (v tomto případě obrázku). Níže je ta samá šipečka s šířkou nastavenou na 300px.

SVG šipečkaA dále zkusíme k šířce nastavit ještě výšku. Nějak disproporčně. Třeba na 20px.

SVG šipečkaNyní, když už máme SVG škálovatelné, udělejme ho ještě stylovatelné. Aby se nám to dobře dělalo, dáme prvkům, které budeme chtít stylovat třídu. Prostě class=“neco“. V našem příkladě je to jednoduché, protože je to vlastně jen jeden tvar, není tedy kam šlápnout vedle.

Můžete samozřejmě použí i id, ale nedoporučoval bych to. Id může být v dokumentu vždy jen jednou a vypisovat ve stylu jaká všechna id to mají mít je docela nic moc a když budete chtít stejně ostylovat další tvar, musíte lézt do stylů, namísto toho abyste přidali tu kterou třídu dalšímu prvku. Stylovat přes id je prostě trochu ošemetné.