Martin Michálek Martin Michálek  – 26. 6. 2017

Používání SVG pro ikony nebo logotypy namísto PNG či GIF obrázků hájím kam vkročím, ale v jedné věci jsou bitmapy zlaté: V přizpůsobování šířce layoutu a zachování poměru stran.

Abychom ale pochopili, proč není dosažení pružnosti SVG jednoduché jako facka, musíme na světlo Boží vytáhnout jednu překvapivou a možná i nepříjemnou pravdu. Nádech…

SVG není obrázek.

… výdech! No jasně, SVG je vektorový dokument, který vkládáme do stránky. Právě proto jej do HTML můžeme dát nejen ve formě obrázku (<img>), ale také jako externí zdroj (<iframe>, <object>) nebo vektory vykreslit přímo (<svg>).

Bitmapy mají jasně definovanou výšku i šířku. Je proto velmi snadné jejich poměr stran zachovat. Jaká je ale výška nebo poměr stran dokumentu?

Nastavení šířky a výšky je k ničemu, použijte viewbox

Mnoho kodérů se domnívá, že u značky <svg> nastaví parametry widthheight – a SVG začne poslouchat. Je to tak ale jen v některých prohlížečích a některých typech vložení do stránky. Celá pravda ovšem je, že nastavením výšky a šířky si mnoho věcí zkomplikujeme.

Vysvětlení je složité, takže vás odkážu na článek, který to rozebírá lépe, než bych to dokázal udělat já. Než se ale do čtení textu „How to Scale SVG“ na CSS Tricks pustíte, ujistěte se, že doma máte dostatečnou zásobu brufenů. css-tricks.com/scale-svg

S brufeny nebo bez, výsledek je stejný. Prostě použijeme parametr viewbox:

<svg viewbox="0 0 100 50">

Kód říká, že výchozí velikost SVG dokumentu je 100 na 50 pixelů, že souřadnicový systém začíná klasicky na bodě nula nula a že si má dokument držet poměr stran.

Jak teď zajistit pružné chování SVG při různých typech vložení do stránky?

Pružné SVG vložené do HTML dokumentu pomocí <svg>

V moderních prohlížečích je to v případě dodržení výše uvedeného opravdu jednoduché. Jen kvůli Internet Exploreru musím přidat obalující značku:

<p class="svg-container">
  <svg viewbox="0 0 900 400" class="svg-content"></svg>
</p>  

Třídu .svg-container pak kvůli Explorerům nastylujeme metodou pro zachování poměru stran, stejně jako to děláme u vkládaných elementů v textu o obrázcích:

.svg-container {
  position: relative;
  width: 100%;
  height: 0;
  padding-top: 100%; /* Poměr stran 1 : 1 */ 
}

.svg-content {
  position: absolute;
  top: 0;
  left: 0;
}

Podívejte na výsledný CodePen. cdpn.io/e/oYOZwz

Pružné SVG vkládané externě pomocí <img>

Opět do zdrojového SVG přidáme viewbox a zrušíme případně přítomné atributy widthheight. Pak stačí klasicky vložit do stránky:

<img src="logo.svg" class="svg"
  alt="Logo firmy">  

Pokud nebudeme nastavovat výšku obrázku, v CSS nemusíme pro moderní prohlížeče nastavovat vůbec nic. Opět jen musíme napravit chování Internet Explorerů:

.svg {
  width: 100%;
}

CodePen s příkladem se na vás těší i tady. cdpn.io/e/VmNbPx

Pružné SVG externě v CSS

Tady je to jednoduché – stačí prostě obrázek umístit na pozadí, zakázat mu opakování a pomocí background-size: contain jej rozprostřít do celé šířky rodiče.

.svg-icon {
  background-image: url('icon.svg');
  background-repeat: no-repeat;  
  background-size: contain;
}

U většiny vektorových obrázků pak chceme definovat poměr stran, který si mají zachovat. Opět si pomůžeme trikem pro zachování poměru stran.

.svg-iconheight: 0;
  padding-bottom: 100%; /* Poměr stran 1 : 1 */ 
}

Tady už není ani žádné speciální nastavení pro Internet Explorer. Hurá!

Mrkněme se spolu na CodePen. cdpn.io/e/NbmgPr

Tím bychom mohli zajištění pružnosti SVG v responzivním layoutu uzavřít pro nejčastěji používané způsoby vložení.

Formát je ale možné do stránky vkládat i dalšími, méně používanými způsoby. Jak zajistit pružnost při vložení do <object>, <iframe>? Poradí vám vrchní odbornice na SVG, Sara Soueidan, v článku „Making SVGs Responsive with CSS“. vrdl.in/yixth

Ale čtěte dál. To nejlepší teprve přijde. Slíbil jsem povídání o responzivních SVG. Zatím jsme se ale bavili jen o těch pružných. O těch, které se přizpůsobují šířce rozvržení stránky. Kromě pružného layoutu ale responzivitu definují ještě změny stylování v určitých velikostech obrazovky. Prostě Media Queries.

(Opravdu) responzivní SVG

Ano, uvnitř SVG můžeme Media Queries úplně v pohodě použít. A ano, někdy se podmínky nevztahují k rozměrům celé stránky, ale k rodiči SVG dokumentu.

K čemu se vztahují Media Queries v SVG?

Podívejme se na jednoduchý příklad, kdy na menších velikostech okna invertujeme barvy loga Vzhůru dolů.

Media Queries prostě napíšeme dovnitř kódu vektorového dokumentu:

<svg>
  <style>
    @media all and (max-width: 500px) {
      #layer-background { display: none; }
      #layer-text path { fill: url(#Gradient_1); }
    }
  </style></svg>

Tady se podmínky v @media vcelku logicky vztahují k šířce okna prohlížeče. cdpn.io/e/vyMRPL

Co když ale vložíme SVG soubor obsahující Media Queries externě?

<img src="vd_logo_mq.svg" 
  width="100" height="100" alt="Logo Vzhůru dolů">

Tušíte správně, podmínky v @media se pak budou vztahovat k šířce obrázku samotného. cdpn.io/e/zZKzRe

Podmínky budou pracovat jako Container Queries.

Tak či tak, mechanismus responzivních SVG má velkou budoucnost: pro ikony, grafy, interaktivní elementy, mapy (!) a další prvky s potřebou měnit hustotu informací nebo formy podle velikosti okna prohlížeče.