O webu
SVG

Zkratka SVG znamená Scalable Vector Graphics – škálovatelná vektorová grafika.

Zásadní rozdíl oproti běžným formátům obrázků jako je PNG, GIF nebo JPG spočívá v tom, že jednotlivé části obrázku jsou přesně popsány XML značkami.

Má-li být na obrázku obdélník (anglicky rectangle), přidá se do <svg> značka <rect>:

<svg width="200" height="100">
 <rect width="200" height="100" fill="#0D6AB7" />
</svg>

Po nastavení rozměrů a barvy výplně (fill) je obrázek na světě:

Jak je vidět na ukázce, kód SVG obrázku jde vložit přímo do HTML.

Po uložení tohoto krátkého kódu do textového souboru s příponou *.svg vznikne plnohodnotný SVG obrázek.

V uloženém souboru je nutné uvést jmenné prostory:

<svg 
  xmlns="http://www.w3.org/2000/svg" 
  xmlns:xlink="http://www.w3.org/1999/xlink"
>
  <!-- samotný obsah obrázku -->
  <rect width="200" height="100" fill="#0D6AB7" />
</svg>

Potom jde použít jako jakýkoliv jiný obrázek standardním způsobem se značkou <img>:

<img src="obrazek.svg">

Nebo jako CSS background:

element {
  background: url(obrazek.svg);
}

Podpora

SVG obrázky jde používat od IE 9. Starší Internet Explorery podporují jiný vektorový formát – VML (Vector Markup Language).

Kromě IE 8 nefunguje SVG ještě ve starém Android Browseru 2.3.

Za rozšíření formátu SVG může hlavně vzestup responsivních webů, protože je najednou nutné zobrazovat grafické prvky v různých rozlišeních.

Kdy použít SVG

SVG se hodí prakticky na všechno kromě fotografií, tedy:

  • loga,
  • ikony,
  • prvky uživatelského rozhraní,
  • vektorové ilustrace

Kromě prostých obrázků se SVG hodí i pro reklamní bannery, infografiky, interaktivní grafické prvky, datové visualisace / grafy, animované ilustrace nebo pro efekty, které jsou aplikovatelné na HTML prvky.

Výhody SVG

  1. Je možné měnit rozměry (width a height) bez ztráty kvality a změny datového objemu.

    Proto je SVG velmi užitečné při tvorbě responsivního webu. Při zvětšení nebo zmenšení obrázku mimo skutečné rozměry je SVG obrázek pořád téměř dokonale ostrý.

    Dále není potřeba vytvářet více obrázků pro různou hustotu pixelů.

  2. Obrázek v SVG vypadá dobře i při zoomování stránky.

  3. Kromě značky <img> či CSS vlastnosti background jde SVG obrázek vložit přímo do stránky.

  4. SVG obrázek jde stylovat pomocí CSS. Jisté části se klidně mohou například přebarvit při najetí myší (:hover). Změny mohou být díky CSS transition i plynulé.

  5. S obrázkem jde manipulovat JavaScriptem. Pomocí JS jde SVG i nakreslit.

  6. Jednotlivé prvky a efekty SVG obrázku jdou výborně animovat.

  7. Do obrázku jde vkládat text, který je skutečně text a ne jen barevné body, které utváří písmena.

Nevýhody

Existují ale i nevýhody:

  1. Základní podpora v prohlížečích je slabší než u klasických formátů, které fungují všude. SVG nepodporuje IE 8 a Android Browser 2.3.

    Vzhledem k tomu, že obrázky často bývají nepostradatelnou součástí stránky, je jejich nezobrazení problematické. Je potom nutné SVG obrázek převést ještě do klasickém formátu pro starší prohlížeče.

    Pokročilejší funkce mají potom podporu proměnlivější a chování se občas liší napříč prohlížeči.

  2. SVG se nehodí pro všechno – pro grafiku, která nevzešla z grafického editoru, ale třeba z fotoaparátu, je formát SVG naprosto nevhodný.

  3. Datová velikost může být u SVG větší než u optimalisovaného PNG obrázku. SVG jde ale ještě komprimovat při přenosu pomocí gzipu, což může jeho velikost srazit na podobnou velikost.

  4. Otevřený zdrojový kód – zdrojový kód SVG si lze prohlížet v libovolném textovém editoru. SVG obrázek se chrání před kopírováním a upravováním ještě hůř než klasické obrázky.

    Není problém si jednotlivé části SVG projít ve vývojářských nástrojích:

    Prohlížení SVG obrázku ve vývojářských nástrojích

Vložení SVG na stránku

Samotné použití SVG na stránce je relativně komplikované. Existují základní tři způsoby:

Značka <img>

Klasická značka <img> funguje i pro SVG:

<img src="obrazek.svg">

Fallback pro starší prohlížeče jde potom zajistit JavaScriptem u události onerror:

<img src="obrazek.svg" 
  onerror="this.onerror=null; this.src='obrazek.png'
">

Případě použít nepopulární detekci na straně serveru. Ta nebude trpět tím, že se nepodporovaným prohlížečům stáhnou dva obrázky.

Vložení SVG kódu do HTML

SVG jde vložit do stránky přímo pomocí elementu <svg>. Při tomto postupu se obrázek stane součástí DOMu. To umožní jeho snadné stylování a ovládání JavaScriptem.

<svg width="200" height="100">
 <rect width="200" height="100" fill="#0D6AB7" />
 <!-- další prvky obrázku -->
</svg>

Takové vložení je pro pohodlnost vhodné řešit na straně serveru. Příklad v PHP:

<?php echo file_get_contents("obrazek.svg"); ?>

Vložení SVG při použití Latte (šablonovací nástroj Nette frameworku):

{!file_get_contents($baseUrl . '/images/obrazek.svg')}

Tento způsob vložení je hodně podobný použití data-uri. Ušetří se tím HTTP požadavek, ale obrázek se nebude cacheovat.

Inline vložení značkou <svg> má lehce horší podporu v prohlížečích. Kromě nepodporovaných prohlížečů IE 8 a Android Browser 2.3 nefunguje tento postup ve starých versích dalších prohlížečů:

Pro nepodporované prohlížeče se nabízí detekce na straně serveru. Případně jde pro inline SVG použít záložní obsah s použitím značek <switch> a <foreignObject>:

<svg width="200" height="100">
  <switch>
    <rect width="200" height="100" fill="#0D6AB7" />
    <foreignObject>
      <div class="zalozni-obrazek"></div>
    </foreignObject>
  </switch>
</svg>

Nebo alternativní obsah umístit do značky <desc>, jejíž obsah se v podporovaných prohlížečích nezobrazí.

<svg width="200" height="100">
  <rect width="200" height="100" fill="#0D6AB7" />
  <desc>
    <div class="zalozni-obrazek"></div>
  </desc>
</svg>

Nabízí se otázka, proč do <desc>/<foreignObject> neumístit přímo značku <img>. To má svůj dobrý důvod: prohlížeče podporující SVG by potom stáhly i záložní obrázek.

CSS background

Pro všelijaké SVG ikonky a podobně se typicky hodí použít CSS pozadí spolu s background-size:

element {
  background: url(obrazek.svg) no-repeat;
  background-size: contain;
}

Při použití CSS backgroundu se nabízí poměrně jednoduché řešení fallbacku pro starší prohlížeče. Podpora SVG je v IE stejná jako podpora vícenásobných obrázků (IE 9+):

element {
  background: url(obrazek.png);
  background-image: url(obrazek.svg), none;
}

Nejprve se nastaví pozadí na PNG obrázek a následně se přepíše dvěma obrázky: SVG obrázkem a ničím (none). Prohlížeče nepodporující vícenásobné pozadí celou deklaraci s background-image zahodí a použijí PNG.

Problematický je v tomto Android Browser 2.3 a starší, který nezná SVG, ale umí vícenásobné pozadí, takže nezobrazí nic.

Obdobně jde využít (ne)podpory CSS gradientů:

element {
  background: url(obrazek.png);
  background-image: url(obrazek.svg), 
                    linear-gradient(transparent, transparent);
}

To sice vyřadí starý Adroid Browser, ale rovněž bude místo SVG jen záložní obrázek v prohlížečích, které SVG podporují: IE 9Opera Mini.

SVG přes <object>

Značka <object> slouží pro universální vložení cizího prvku do stránky.

Výhoda je v tom, že přímo do značky lze umístit obsah, který prohlížeč použije v případě, že objekt nezná.

<object type="image/svg+xml" data="obrazek.svg">
  <div class="zalozni-obrazek"></div>
</object>

Záložní obrázek je vhodné vložit prostřednictvím CSS pozadí a ne značkou <img>, aby záložní obrázek zbytečně nestahovaly prohlížeče, které umí <svg>.

Značka <image>

Značka SVG umožňuje pomocí elementu <image> vložit v rámci <svg> libovolný obrázek:

<svg width="200" height="100">
  <image 
    xlink:href="obrazek.svg" 
    src="obrazek.png"
    width="200" height="100" />
</svg>

Z toho jde vymyslet zajímavý fallback pro prohlížeče, co SVG neznají. Značka <image> se mimo element <svg> totiž chová prakticky stejně jako <img>, takže jde do src připojit záložní obrázek v PNG.

Starší prohlížeče budou neznámou značku <svg> ignorovat a <image> zobrazí jako <img>. Prohlížeče, co SVG znají, potom budou zase ignorovat atribut src a zobrazí obrazek.svg:

Je-li obdélník modrý, zobrazuje se SVG. V nepodporovaných prohlížečích se zobrazuje následující PNG obrázek:

PNG obrázek

Test podpory SVG

Detekovat podporu SVG v JavaScriptu jde pohodlně s využitím knihovny Modernizr:

if (!Modernizr.svg) {
  // SVG není podporováno
}

Samostatný test podpory SVG je tam udělán následovně:

function supportsSVG() {
  return !!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', "svg").createSVGRect;
}

SVG fallback

Pro případ, že prohlížeč SVG nepodporuje, se zdá být nejsnazší fallback s CSS backgroundem, který využívá podobné podpory SVG jako vícenásobného pozadí.

element {
  background: url(obrazek.png);
  background-image: url(obrazek.svg), none;
}

Není závislý na JS a funguje skoro všude. Pro vyšší jistotu se může přidat třída .no-svg pro <html>/<body> na základě detekce podpory SVG v JS nebo dle detekce problematického zařízení na serveru.

A v CSS mít ještě zálohu:

element {
  background: url(obrazek.png);
  background-image: url(obrazek.svg), none;
}
.no-svg element {
  background-image: url(obrazek.png);
}

Další příklady SVG fallbacků:

SVG ikony / sprite

Pro optimalisaci počtu HTTP spojení bývá zvykem všechny obrázky spojit do jednoho a jednotlivé obrázky zobrazovat vhodně nastaveným background-position.

  • CSS sprite – spojení všech obrázků do jednoho

Menší vsuvka ohledně budoucnosti:

Protokol HTTP/2

Protokol HTTP/2 řeší problém se stahováním velkého množství externích souborů. Po jeho rozšíření nebude problém připojit do stránky desítky souborů s ikonkami bez zpomalení načítání.

Používání CSS spritů a spojování souborů bude potom naopak anti-pattern, protože bude komplikovat cacheování.

Klasický CSS sprite postup jde použít i v případě SVG. Jen se tím při fixních rozměrech nic moc nezíská (kromě ostrých ikonek při zoomu a na displejích s velkou hustotou pixelů).

Různá velikost

Aby šly ikonky snadno zvětšovat a zmenšovat, je užitečné mít posice jednotlivých obrázků v relativních jednotkách – třeba em.

Díky tomu, že rozměry i posice obrázku jsou v em jednotkách, stačí pro změnu velikosti změnit font-size.

Živá ukázka – změna velikosti SVG ikonek ve spritu

Sprite z SVG ikonkami

Na ukázce je vidět, že není rozumné ikonky nalepit úplně na sebe, ale je dobré ponechat nějaké odsazení.

Dále ke čtení:

SVG v data-uri

Jelikož SVG má stejnou podporu jako Data URI (zápis obsahu souboru pomocí protokolu data:), není příliš problém data: použít místo vytváření SVG spritu:

.icon {
  background-image: url('data:image/svg+xml;…');
}

Každá ikonka potom má vlastní background-image, takže se nemusí kouzlit s background-position.

Veškeré SVG obrázky se stanou součástí CSS souboru.

Existují hotové nástroje, které umí z SVG ikonek vygenerovat hotové řešení s fallbacky:

  • Iconizr – vygeneruje SVG sprite pro CSS background, data-uri i fallbacky v PNG
  • Grumpicon – vygeneruje SVG do data-uri s PNG fallbacky

Vkládání obrázků pomocí data-uri je dobré zvážit. Má to i své nevýhody:

  1. Obrázky se kešují spolu s CSS souborem, což nemusí být ideální. Změna jediného obrázku vede k nutnosti znovu stahovat celé CSS. Změna CSS v podstatě zneplatní všechny obrázky.

  2. Datově velké obrázky budou zdržovat stažení CSS. Měly by tedy být mimo kritické CSS načítané asynchronně, jinak budou blokovat vykreslení.

  3. Vždy se stáhnou všechny obrázky, ačkoliv na dané stránce nemusí být potřeba.

Pro větší obrázky tedy není tento postup moc šťastný. Detailněji se problematikou zabývá článek:

Skutečný SVG sprite

SVG nabízí ještě jeden elegantní způsob, jak sprity vytvořit.

Do značky <svg> přímo do HTML kódu jde umístit všechny ikonky. Slouží k tomu značka <symbol>.

<svg style="display:none;">
  <symbol id="id-ikony" viewBox="0 0 32 32">
    <path d="…" fill="#000000"></path>
  </symbol>
  <symbol id="dalsi-ikona" viewBox="0 0 32 32">
    <!-- obsah další ikony -->
  </symbol>
</svg>

Používat element <symbol> není úplně nutné. Jde použít i skupinu <g>, ale není to tak dobré. Symbol totiž prohlížeče nerenderují před použitím.

Element <svg> je skrytý pomocí display: none, jinak by na stránce zabíral nějaký ten prostor.

Jednotlivé nadefinované symboly jde následně použít kdekoliv na stránce pomocí značky <use>:

<svg class="ikona">
  <use xlink:href="#id-ikony"></use>
</svg>

Třída u <svg> slouží pro další stylování. Tímto postupem je navíc možné měnit vlastnosti SVG obrázku pomocí CSS souboru připojeného ke stránce (při jiném způsobu vložení musí být CSS v *.svg souboru).

Tuto techniku dokáže používat online nástroj Icomoon:

  • Icomoon – nástroj pro vytvoření SVG spritů

Nevýhoda nastrkání všech SVG ikonek do hlavičky je jasná – ikonky se nebudou ukládat do cache.

Teoreticky je možné ikonky cacheovat JavaScriptem do localStorage:

Nebo SVG definici ikonek stáhnout AJAXem, což použití cache umožní, ale opět to bude závislé na JavaScriptu.

I problém s kešováním se SVG snaží řešit:

SVG sprite z externího souboru

Do konstrukce <use xlink:href="#id-ikony"></use> jde zadat externí soubor se všemi definicemi ikonek a odkázat se na konkrétní symbol:

<svg class="ikona">
  <use xlink:href="ikony.svg#id-ikony"></use>
</svg>

Tento postup ale bohužel nefunguje v Internet Exploreru (ani v IE 9+, který SVG podporuje).

Detailnější popis SVG spritů:

Grafické programy pro SVG

Pro vlastní vytváření SVG je potřeba nějaký ten grafický editor:

Inkscape

Stáhnout Inkscape

Inkscape je zdarma pro všechny platformy – Windows, Mac OS X, Linux.

Kreslení SVG v Inkscape

Výsledný SVG obrázek je potřeba pro použití pročistit od zbytečných značek.

Adobe Illustrator

Stáhnout Illustrator

Poměrně drahý program, který se pro pouhou úpravu SVG asi nevyplatí kupovat.

Online editory

Vzhledem k povaze SVG není takový problém vytvořit editor přímo v prohlížeči.

  • SVG edit – kreslení SVG přímo v prohlížeči

Optimalisace SVG

Z grafických editorů typicky lezou zbytečně datově velké SVG obrázky. Existují nástroje pro optimalisaci a kompresi.

Mnohdy jde dosáhnout i 50% úspor:

  1. Odstraněním meta dat, které do SVG obrázku uložil grafický editor.
  2. Zjednodušením a zkombinováním cest (<path>).
  3. Snížení počtu desetinných míst typicky vede k největším úsporám.
  4. Pro opakované styly více prvků jde použít CSS.

Úpravy pochopitelně mohou změnit výsledný vzhled obrázku.

SVGOMG

SVGOMG online

SVGOMG je online nástroj běžící přímo v prohlížeči.

Díky tomu jde při různých stupních optimalisace přímo pozorovat výsledek.

Zároveň se zobrazuje míra úspory velikosti.

SVGOMG

Využívá SVGO, které jde použít i pro automatisovanou optimalisaci na lokálním PC.

  • SVGO – optimalisuje SVG obrázky v Node.js

SVG Editor

SVG Editor online

Hodně podobný nástroj jako SVGOMG.

Další informace o optimalisaci SVG obsahují články:

Převod PNG na SVG

Pro použití v responsivním designu se hodí PNG obrázky nahrazovat SVG formátem.

Existuje řada online nástrojů, které se snaží automaticky převádět PNG do SVG. Rozumně to funguje pouze pro jednoduché obrázky.

Složitější věci je nutné ručně překreslit. Některé převodní nástroje pouze zabalí PNG/GIF obrázek do značky <svg>, což je k ničemu.

Text v SVG

Skutečný text se do SVG obrázku zadává značkou <text>:

Je čas

Takový text z obrázku je potom perfektně přístupný a je i možné ho označit myší.

Je čas web design

S textem jde potom provádět spoustu věcí. Třeba roztáhnout písmo podle šířky a obarvit ho gradientem.

Další úpravy a animace textu popisuje následující presentace:

SVG ikony ke stažení

Hromadu ikon v SVG je možné zdarma stáhnout z internetu:

  • Noun Project – ikonky pro všechno se snadnou možností prohledávat
  • SVG Icons – několik hotových sad ikon připravených ke vložení

Odkazy jinam

SVG animace

SVG bannery

SVG filtry a textury

Generátory

Grafy

WebGL

Přednášky