
W dokumentach HTML możemy pokazywać, ukrywać i przestawiać fragmenty strony zależnie od warunków viewportu. Jeśli okno przeglądarki ma 480 pikseli szerokości, nawigację poziomą zamienimy na pionową listę zwijaną. Podobnie da się postąpić z SVG i media queries.
Ten artykuł to fragment książki Tiffany, CSS Master, wydanie trzecie. Zajrzyj do niej, jeśli chcesz opanować kolejne zaawansowane możliwości CSS3, takie jak Flexbox i Grid.
CSS-a używamy nie tylko z HTML-em, ale też z SVG, czyli Scalable Vector Graphics. SVG to język znaczników opisujący płaskie, dwuwymiarowe obrazy. Ponieważ jest językiem znaczników, ma własny model obiektowy dokumentu i da się go stylować CSS-em.
Dzięki CSS-owi wygląd SVG może zmieniać się w reakcji na działania użytkownika. Ten sam dokument SVG można też osadzić w kilku miejscach i pokazywać lub ukrywać jego części zależnie od szerokości viewportu.
Wszystkie główne silniki przeglądarek od lat obsługują SVG 1.1. Nad funkcjami SVG 2 wciąż jednak trwają prace. W chwili pisania tego tekstu część opisanych tu rzeczy ma ograniczone wsparcie przeglądarek. Kiedy to czytasz, może być już inaczej. Śledź metazgłoszenie Chromium Implementacja funkcji SVG 2 – pokazuje postęp prac w przeglądarkach opartych na Chromium. Metazgłoszenie Wsparcie dla funkcji SVG 2 odpowiada za Firefoksa, a Implementacja SVG 2 za WebKita i Safari. Grzebanie w issue trackerach bywa męczące, ale na razie to najlepszy sposób, żeby śledzić wsparcie dla SVG 2.
Zanim przejdziemy dalej, zobaczmy jednak, czym jest SVG i dlaczego warto po niego sięgać.
Grafika wektorowa a grafika rastrowa
Większość obrazów używanych dziś w sieci to grafiki rastrowe, nazywane też bitmapami. Obrazy rastrowe składają się z pikseli ułożonych na stałej siatce, o określonej liczbie pikseli na cal. JPEG, WebP, GIF i PNG to formaty rastrowe.
Grafika rastrowa jest zależna od rozdzielczości. Obraz PNG w 144 PPI (piksele na cal) wygląda świetnie na urządzeniu o rozdzielczości 144 PPI. Ten sam plik wyświetlony na ekranie o wyższej rozdzielczości (400 PPI) potrafi być rozmyty. Obrazy rastrowe mają też stałe wymiary i wypadają najlepiej w oryginalnym rozmiarze. Przeskalowanie obrazu 150 na 150 pikseli do 300 na 300 pikseli go zniekształci.
Formaty wektorowe, zamiast pikseli na siatce, opisują figury podstawowe – koła, prostokąty, linie czy ścieżki – z których zbudowany jest obraz, oraz ich położenie w układzie współrzędnych dokumentu. Dlatego grafika wektorowa jest niezależna od rozdzielczości i zachowuje jakość niezależnie od rozdzielczości i wymiarów ekranu.
Niezależność od rozdzielczości to największa zaleta SVG. Obrazy powiększamy i pomniejszamy bez straty jakości. Ten sam plik wygląda dobrze na ekranach o wysokim i niskim PPI. SVG słabo za to radzi sobie z ilością danych o kolorze, jakiej wymagają fotografie. Lepiej sprawdza się w rysunkach i kształtach. Używaj go zamiast PNG i GIF-ów oraz jako elastyczniejszego zamiennika fontów ikonowych.
Druga zaleta SVG: został zaprojektowany do współpracy z pozostałymi językami sieci. Obrazy SVG możemy tworzyć, modyfikować i przetwarzać JavaScriptem. Albo – co zobaczymy dalej – stylować i animować CSS-em.
Podpinanie CSS-a do dokumentów SVG
Używanie CSS-a z SVG bardzo przypomina używanie go z HTML-em. Style przypiszemy w atrybucie style elementu SVG, osadzimy je w dokumencie elementem <style> albo podepniemy zewnętrzny arkusz. Zalety i wady każdej metody są takie same jak w HTML-u.
Atrybut style
Oto prosty dokument SVG, którego kod rysuje czarne koło:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200"
➥enable-background="new 0 0 200 200">
<circle cx="101.3" cy="96.8" r="79.6" />
</svg>
Poniższy obraz pokazuje, jak ten kod renderuje przeglądarka.

Nadajmy naszemu kołu różowe wypełnienie, korzystając z CSS-a i atrybutu style:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200"
➥enable-background="new 0 0 200 200">
<circle cx="101.3" cy="96.8" r="79.6" style="fill: #f9f" />
</svg>
Efekt widać poniżej.

Tu pojawia się pierwsza różnica między CSS-em w HTML-u a CSS-em w SVG: nazwy właściwości. Wiele właściwości CSS używanych w dokumentach HTML nie działa w SVG i odwrotnie. Wrócimy do tego w dalszej części rozdziału.
Atrybut style to oczywiście nie najlepszy sposób na pisanie CSS-a. Utrudnia ponowne wykorzystanie stylów w wielu elementach i dokumentach. Lepiej sięgnąć po style osadzone w dokumencie albo podlinkowane.
Osadzanie CSS-a w dokumentach SVG
Zamiast atrybutu style możemy użyć elementu <style>:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0
➥ 200 200" enable-background="new 0 0 200 200">
<style type="text/css">
circle {
fill: #0c0;
}
</style>
<circle cx="101.3" cy="96.8" r="79.6" />
</svg>
Osadzenie CSS-a w dokumencie SVG pozwala użyć tych samych stylów dla wielu elementów w tym samym dokumencie, ale nie pozwala dzielić ich między dokumentami. Do logo i ikon w zupełności wystarczy. Jeśli jednak budujesz coś w rodzaju biblioteki stylów wykresów, lepszy będzie zewnętrzny plik CSS.
Zwykłym edytorem tekstu dodasz CSS także do obrazów SVG utworzonych w programach takich jak Sketch, Inkscape czy Illustrator. Nie przeszkodzi to w dalszej edycji obrazu w programie graficznym, ale jeśli zapiszesz w nim plik, aplikacja może nadpisać albo usunąć twój CSS.
Podpinanie zewnętrznego pliku CSS do SVG
Tak jak w HTML-u, zewnętrzny plik CSS pozwala dzielić style między wieloma dokumentami SVG. Żeby go podpiąć, dodaj <? xml-stylesheet ?> na początku pliku SVG:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="https://www.gekkode.com/pl/style.css" type="text/css"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0
➥ 200 200" enable-background="new 0 0 200 200">
<circle cx="101.3" cy="96.8" r="79.6" />
</svg>
Element <link>
Możesz też użyć HTML-owego <link>. Przy tej metodzie trzeba dopisać atrybut xmlns, tak jak niżej:
<link href="style.css" type="text/css" rel="stylesheet"
➥ xmlns="http://www.w3.org/1999/xhtml" />
Uwaga: niektóre starsze przeglądarki wymagają, żeby <link> był otoczony znacznikiem <defs> albo <g>.
<link> nie jest elementem SVG. Należy do HTML-a i XHTML-a. XHTML to odmiana HTML-a parsowana według reguł XML-a. A reguły XML-a pozwalają zapożyczać elementy i ich zachowanie z innych dialektów XML, choćby z XHTML-a. Trzeba tylko wskazać przeglądarce przestrzeń nazw, do której element należy, atrybutem xmlns.
Reguła @import
Zewnętrzny arkusz podepniemy również regułą @import umieszczoną między znacznikami <style> i </style>:
<style type="text/css">
@import("https://www.gekkode.com/style.css");
</style>
Ta metoda działa podobnie do <link>.
SVG a element <img>: ograniczenia
Podpinanie zewnętrznych zasobów do plików SVG, w tym plików CSS, nie działa w elemencie <img>. To wbudowane w przeglądarki ograniczenie bezpieczeństwa.
Jeśli chcesz używać podlinkowanego CSS-a w obrazach SVG, masz dwie możliwości:
- użyć elementu
<style>w dokumencie SVG i osadzić CSS w środku, - użyć elementu
<iframe>albo<object>(zobacz uwagę niżej).
Zwykle lepiej sięgnąć po <iframe> niż po <object>. Za to <object> może być dzieckiem elementu <a>, a <iframe> nie. Zarówno <iframe>, jak i <object> udostępniają drzewo dokumentu SVG drzewu dokumentu nadrzędnego. Możemy więc sięgać do niego JavaScriptem (na przykład przez document.querySelector('iframe').contentDocument).
SVG inline a zasoby zewnętrzne
Kiedy wstawiasz SVG bezpośrednio do HTML-a, przeglądarka nie wczyta zewnętrznych zasobów, do których odwołuje się dokument SVG. Możemy za to podpiąć CSS dla naszego SVG w sekcji <head> dokumentu HTML:
<head>
⋮
<link href="svg.css" type="text/css" rel="stylesheet" />
</head>
Elementy SVG w dokumentach HTML są też częścią drzewa dokumentu HTML. Jeśli używasz SVG inline, spokojnie połączysz reguły CSS dla HTML-a i dla SVG w jednym arkuszu.
Różnice między SVG a HTML-em
SVG i HTML to co prawda dwa języki znaczników, ale dzielą je dwie istotne różnice, które wpływają na współpracę z CSS-em:
- SVG nie stosuje się do modelu pudełkowego CSS,
- SVG nie ma schematów pozycjonowania.
SVG nie stosuje się do modelu pudełkowego CSS
W HTML-u układ CSS działa według reguł modelu pudełkowego. SVG używa natomiast współrzędnych. Rządzi się czymś, co najlepiej rozumieć jako „model kształtu”.
Kształty SVG nie ograniczają się do prostokątnych pudełek. Dlatego większość właściwości związanych z modelem pudełkowym nie działa na elementach SVG. Nie zmienisz na przykład padding ani margin elementu SVG. Nie użyjesz też właściwości box-sizing, box-shadow, outline ani border-*. Grid, floaty i Flexbox również nie zadziałają.
CSS-em ustawisz za to i zmienisz całą grupę właściwości oraz wartości atrybutów SVG. Pełną listę znajdziesz w specyfikacji SVG 2, choć w większości przeglądarek jest ona wdrożona tylko częściowo. Niektóre właściwości CSS, na przykład filter, działają zarówno w SVG, jak i w HTML-u. Kilka z nich omówimy w tym rozdziale przy okazji konkretnych technik.
SVG nie ma schematów pozycjonowania
Kiedy CSS-a używamy z HTML-em, pudełka elementów mogą:
- istnieć w normalnym przepływie,
- zostać z niego wyjęte właściwością
float, - zostać z niego wyjęte właściwością
position.
Specyfikacja CSS nazywa to schematami pozycjonowania. W SVG one nie istnieją. Właściwość position nie robi z elementami SVG nic. Tak samo właściwości zależne od pozycjonowania, czyli top, left czy bottom. W dokumencie SVG nie ustawisz też floatów.
Zamiast tego SVG rozmieszcza elementy w układzie współrzędnych. Żeby narysować <circle>, podajesz współrzędne środka w atrybutach cx i cy oraz długość promienia w atrybucie r. Wielokąt to seria współrzędnych punktów i odcinków poprowadzonych między nimi. Innymi słowy: określasz, w którym miejscu płótna SVG element zostanie narysowany, ale nie „pozycjonujesz” go w rozumieniu CSS-a.
Z pozycjonowaniem wiąże się kolejny brak: SVG nie zna właściwości z-index ani kontekstów układania.
Uwaga: specyfikacja SVG 2 definiuje zachowanie z-index i kontekstów układania w dokumentach SVG, ale większość przeglądarek jeszcze tego nie obsługuje.
Elementy SVG układają się w stos zgodnie z kolejnością w źródle. Te, które pojawiają się później, lądują na wierzchu. Żeby zmienić kolejność układania, musisz przestawić je w źródle albo poprzestawiać w drzewie DOM JavaScriptem.
Prawdę mówiąc, większość właściwości CSS 2.1 nie działa w dokumentach SVG. Wyjątkiem są animacje i transformacje, display, overflow, visibility, filter oraz kilka właściwości związanych z fontem i tekstem. W zamian sięgasz po właściwości stylu specyficzne dla dokumentów SVG. Większość z nich da się też zapisać jako atrybuty elementów SVG.
Stylowanie elementów SVG
Oto prosty przykład stylowania elementów SVG za pomocą CSS-a. Zaczynamy od dokumentu SVG, który jest osobnym plikiem:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="https://www.gekkode.com/pl/styles.css" type="text/css" ?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink=
➥"http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 497
➥ 184" enable-background="new 0 0 497 184" xml:space="preserve">
<polygon id="star" points="77,23.7 98.2,66.6 145.5,66.5 111.2,
➥106.9,119.3,154 77,131.8 34.7,154 42.8,106.9 8.5,67.5 55.8,
➥66.6 "/>
<circle id="circle" cx="245" cy="88.9" r="67.5"/>
</svg>
Ten kod tworzy obraz widoczny niżej.

Choć w dokumentach SVG nie użyjemy większości właściwości CSS, kolor elementu zmienimy bez problemu. Zróbmy naszą gwiazdę na żółto:
#star {
fill: hsl( 44, 100%, 50% );
}
fill zobaczysz często jako atrybut znacznika SVG, na przykład <circle fill="rgb( 255, 185, 0 )" cx="3" cy="10" r="100"> – ale to również właściwość, której możesz użyć w CSS-ie.
CSS-em ustawimy też stroke, czyli obrys kształtu SVG. Obrys istnieje nawet wtedy, gdy nie zdefiniowano stroke. Dajmy naszemu kołu ciemnoniebieską kreskowaną obwódkę o szerokości dziesięciu pikseli. Właściwość fill ustawimy przy okazji na cornflowerblue:
circle {
fill: cornflowerblue;
stroke: darkblue;
stroke-width: 10;
stroke-dasharray: 10, 15;
stroke-linecap: round;
}
Razem daje to poniższy efekt.

Atrybuty SVG jako właściwości CSS
CSS-em ustawimy również współrzędne części kształtów: <rect>, <circle> i <ellipse>. Zwykle korzystalibyśmy tu z atrybutów SVG:
<svg viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg">
<rect x="20" y="200" width="300" height="300" fill="#f60" />
</svg>
SVG 2 przedefiniował jednak część atrybutów jako właściwości geometryczne. Ich wartości możemy więc ustawiać w CSS-ie:
<svg viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg">
<style type="text/css">
rect {
x: 20px;
y: 50px;
width: 300px;
height: 300px;
fill: #f60;
}
</style>
<rect />
</svg>
W CSS-ie ustawisz właściwości współrzędnych (x i y), współrzędnych środka (cx i cy) oraz promienia (rx, ry i r). To samo dotyczy width i height. W atrybutach SVG jednostki są opcjonalne. W wartościach CSS natomiast są wymagane. Dla wymienionych właściwości poprawne są zarówno długości, jak i procenty, pamiętaj jednak, że długości działają w dokumentach SVG trochę inaczej. S w skrócie SVG oznacza scalable. Obliczony rozmiar elementu SVG zależy również od:
- obliczonych wartości
widthiheightgłównego elementu SVG, - wartości atrybutu
viewBoxtego elementu, - każdej transformacji skali nałożonej na element lub na jego przodków.
Innymi słowy: rogi naszego elementu <rect> leżą w punktach (20, 50), (20, 320), (350, 320) i (20, 350) układu współrzędnych SVG. Rzeczywiste wymiary mogą być jednak większe albo mniejsze, zależnie od powyższych czynników.
Nie wszystkie atrybuty SVG są dostępne z poziomu CSS-a – przynajmniej nie we wszystkich przeglądarkach. Chrome i Edge obsługują na przykład funkcję path() do ustawiania danych ścieżki, czyli atrybutu d:
path {
d: path("M 454.45223,559.21474 -304.96705,163.45948 417.4767,-296.33928 Z");
}
Na dziś to jedyne przeglądarki, które to potrafią. Prace nad wsparciem w Firefoksie i w WebKicie jeszcze się nie zaczęły.
W przypadku pozostałych kształtów specyfikacja SVG 2 jest wręcz niespójna. Na dziś właściwości elementów <line>, <polyline> i <polygon> musisz ustawiać atrybutami.
Nie jesteśmy przy tym skazani na selektory typu (czyli elementu). Małe, średnie i duże koła zdefiniujemy równie dobrze selektorami klas:
<svg viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg">
<style type="text/css">
.small {
cx: 20px;
cy: 20px;
r: 20px;
fill: #0c0;
}
.medium {
cx: 80px;
cy: 80px;
r: 60px;
fill: #fc0;
}
.large {
cx: 220px;
cy: 220px;
r: 120px;
fill: #00f;
}
</style>
<circle class="small" />
<circle class="medium" />
<circle class="large" />
</svg>
Niezależnie od selektora, zapisanie właściwości w składni CSS ułatwia też ich animowanie. Zobaczymy to w następnej sekcji.
Animacje i przejścia właściwości CSS w SVG
CSS w SVG robi się ciekawszy, kiedy dorzucimy przejścia i animacje. Działa to tak samo jak animowanie elementów HTML CSS-em, tylko na właściwościach specyficznych dla SVG. Zbudujmy efekt migoczącej gwiazdy na podstawie takiego dokumentu SVG:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px"
➥ y="0px" viewBox="0 0 497 184" xml:space="preserve">
<defs>
<link href="twinkle.css" type="text/css" rel="stylesheet"
➥ xmlns="http://www.w3.org/1999/xhtml"/>
</defs>
<polygon class="star" points="77,23.7 98.2,66.6 145.5,66.5 111.2
➥,106.9 119.3,154 77,131.8 34.7,154 42.8,106.9 8.5,67.5
➥ 55.8,66.6 "/>
<polygon class="star twinkle" points="77,23.7 98.2,66.6 145.5,
➥66.5 111.2,106.9 119.3,154 77,131.8 34.7,154 42.8,106.9
➥ 8.5,67.5 55.8,66.6 "/>
</svg>
Dokument zawiera dwa wielokąty w kształcie gwiazdy, oba z klasą star. Efekt migotania uzyskamy, animując pierwszy z nich. Oto nasz CSS:
@keyframes twinkle {
from {
fill-opacity: .4;
}
to {
fill-opacity: 0;
transform: scale( 2 );
}
}
.star {
fill: rgb( 255,195,0 );
transform-origin: 50% 50%;
}
.twinkle {
animation: twinkle 1.5s infinite forwards ease-in;
}
Użyliśmy tu właściwości fill-opacity, charakterystycznej dla SVG. Zasada jest taka sama jak w CSS-ie: jeśli wartość właściwości stylu SVG da się interpolować, da się ją animować albo objąć przejściem. Poniższy obraz pokazuje dwa różne momenty animacji.

Weźmy kolejny przykład. Tym razem zbudujemy efekt rysowania, animując przejście właściwości stroke-dasharray. Oto nasz dokument SVG:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
➥xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 200 200" enable-background="new 0 0 200 200">
<circle fill="transparent" stroke-width="16" cx="101.3"
➥ cy="96.8" r="79.6"/>
</svg>
stroke-dasharray przyjmuje listę długości lub procentów rozdzielonych przecinkami, które tworzą wzór kreskowania. Wartości nieparzyste ustalają długość kreski, parzyste – długość przerwy. stroke-dasharray o wartości 5, 10 daje kreskę długą na 5px i przerwę 10px między kolejnymi kreskami. Wartość 5, 5, 10 daje na przemian kreski 5px i 10px, z przerwą 5px pomiędzy nimi.
stroke-dasharray pozwala zbudować efekt rysowania: zaczynamy od zerowej kreski i dużej przerwy, a kończymy na długiej kresce i zerowej przerwie. Między tymi stanami robimy przejście. Nasz CSS wygląda tak:
circle {
transition: stroke-dasharray 1s ease-in;
fill: transparent;
stroke-dasharray: 0, 500;
}
.animate {
stroke-dasharray: 500, 0;
}
Na początku przejścia obrys jest niewidoczny, bo długość kreski wynosi 0, a przerwa 500. Kiedy dodamy naszemu kołu klasę animate, długość kreski rośnie do 500, a przerwa znika. Efekt przypomina rysowanie koła cyrklem. Dlaczego 500? To najmniejsza wartość, przy której ten konkretny efekt wychodzi.
Animowane ścieżki: co przyniesie przyszłość
Pamiętasz przykład definiowania ścieżki w CSS-ie z poprzedniej sekcji? Kiedyś być może uda się animować ścieżki CSS-em we wszystkich przeglądarkach:
path {
d: path("M357.5 451L506.889 192.25H208.111L357.5 451Z");
transition: d 1s ease-in-out;
}
.straighten {
d: path("M357.5 8871L406 -10113.75H208.111L357.5 351Z");
}
Na razie animowanie definicji ścieżki w ten sposób obsługują tylko przeglądarki oparte na Chromium, czyli Google Chrome i Microsoft Edge. W pozostałych sięgnij po bibliotekę JavaScript, na przykład GreenSock z MorphSVGPlugin. Poza zgodnością z przeglądarkami GreenSock i MorphSVGPlugin ułatwiają morfing między dwoma kształtami, niezależnie od liczby punktów w każdym z nich.
SVG z media queries
W dokumentach HTML możemy pokazywać, ukrywać i przestawiać fragmenty strony zależnie od warunków viewportu. Jeśli okno przeglądarki ma 480 pikseli szerokości, nawigację poziomą zamienimy na pionową listę zwijaną. Podobnie postąpimy z media queries i dokumentami SVG. Weźmy logo, na przykład logo fikcyjnej firmy Hexagon Web Design & Development, widoczne niżej.

Bez media queries takie logo SVG po prostu rozciągałoby się albo kurczyło do rozmiaru viewportu lub kontenera. Z media queries możemy zrobić coś sprytniejszego.
Rozróżnijmy viewport dokumentu HTML i viewport dokumentu SVG. Przy SVG inline oba są tym samym: dokument SVG zachowuje się jak każdy inny element HTML. Kiedy jednak dokument SVG jest podlinkowany – przez <iframe>, <object> albo <img> – mamy do czynienia z viewportem samego dokumentu SVG.
Media queries działają w obu przypadkach, ale przy podlinkowanym dokumencie SVG jego viewport jest niezależny od dokumentu HTML. Rozmiar okna przeglądarki nie decyduje wtedy o rozmiarze viewportu SVG, decydują o nim wymiary elementu <object>, <iframe> lub <img>. Weźmy taki (skrócony) dokument SVG:
<svg version="1.1" id="HexagonLogo" xmlns="http://www.w3.org/2000/
➥svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
➥ viewBox="0 0 555 174" xml:space="preserve">
<defs>
<style type="text/css">
/* CSS goes here */
</style>
</defs>
<g id="hex">
<polygon id="hexagonbg" points="55.2,162 10,86.5 55.2,11
➥ 145.5,11 190.7,86.5 145.5,162 "/>
<path id="letterH" fill="#FFFFFF" d="M58,35.5h33v35.2h18.
➥4V35.5 h33.2v103.4h-33.2v-38.3H91v38.3H58V35.5z M77.5,126.5V87.
➥3h45.6v39.2h4V47.9h-4v35.6H77.5V47.9h-4v78.6H77.5z"/>
</g>
<g id="word-mark">
<g id="hexagon-word">
...
</g>
<g id="web-design-and-dev">
...
</g>
</g>
</svg>
Uwaga: pełne demo tej techniki, razem z kompletnym źródłem tego dokumentu SVG, jest dostępne online.
W mniejszych viewportach pokażmy samo H w sześciokątnym symbolu:
@media (max-width: 320px) {
[id=word-mark] {
display: none;
}
}
Od teraz, kiedy kontener naszego SVG ma 20em lub mniej, widoczna będzie tylko symboliczna część logo.

Żeby wywołać ten widok z poziomu dokumentu HTML, ustaw szerokość kontenera SVG:
<iframe src="hexlogo.svg" style="width: 320px; border:0"></iframe>
Jak widać na powyższym obrazie, nasz SVG zachowuje swoje wymiary własne, mimo że część została ukryta. To niestety ograniczenie SVG. Żeby sobie z nim poradzić, musimy zmienić viewBox dokumentu SVG, ale tylko wtedy, gdy viewport jest mniejszy niż dany rozmiar. Świetny przypadek użycia dla matchMedia.
viewBox, jak sama nazwa wskazuje, wyznacza widoczny obszar elementu SVG. Zmieniając go, decydujemy o tym, która część obrazu SVG wypełnia viewport. Oto przykład, w którym matchMedia i media query aktualizują atrybut viewBox:
<script type="text/javascript">
const svg = document.querySelector( 'svg' );
/* Zapisanie pierwotnej wartości w zmiennej */
const originalViewBox = svg.getAttribute( 'viewBox' );
/* Definicja media query i jej obiektu */
const mq = matchMedia( '( max-width: 320px )' );
/* Definicja handlera */
const updateViewBox = () {
if (mq.matches) {
/* Zmiana wymiarów viewBox, żeby pokazać sześciokąt */
svg.setAttribute( 'viewBox', '0 0 200 174' );
} else {
svg.setAttribute( 'viewBox', originalViewBox );
}
}
svg.addEventListener( 'SVGLoad', updateViewBox );
/* Odpala się, gdy warunek media query się zmieni */
mq.addEventListener( 'change', updateViewBox );
</script>
Od teraz, kiedy kontener SVG ma 320 pikseli lub mniej, atrybut viewBox przyjmie wartość "0 0 200 174". Powyżej 320 pikseli viewBox wraca do wartości początkowej.

Ponieważ technika opiera się na atrybucie onload albo na zdarzeniu SVGLoad, warto osadzić CSS i JavaScript wewnątrz pliku SVG. Przy zewnętrznym arkuszu SVGLoad potrafi zadziałać, zanim powiązany CSS skończy się wczytywać.
Media queries a background-size
Dokumenty SVG i media queries nie ograniczają się do obrazów na pierwszym planie. Viewport SVG przeskalujemy również właściwością CSS background-size.
Zaczniemy od takiego dokumentu SVG:
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
➥ xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
➥ viewBox="-20 -20 250 250" xml:space="preserve">
<style type="text/css">
circle {
stroke: #000;
stroke-width: 30;
fill: #009688;
}
@media ( width: 100px ) {
circle {
fill: #673ab7;
}
}
@media ( width: 300px ) {
circle {
fill: #ffc107;
}
}
</style>
</defs>
<circle cx="100" cy="100" r="100" />
<circle cx="100" cy="100" r="50" />
</svg>
To prosty przypadek. Nasze elementy <circle> dostają nowe fill przy określonych szerokościach viewportu. Domyślnie fill jest morski, przy 100 pikselach zmienia się na fioletowy, a przy 300 pikselach, na żółty.
Żeby to zadziałało, musimy użyć obrazu SVG jako tła i ustawić w selektorze background-size. Tutaj obraz posłuży za tło elementu <body> oraz elementów <li>:
body, li {
background: url(circles.svg);
}
body {
background-color: #9c27b0;
background-size: 300px auto;
}
li {
background-position: left center;
background-repeat: no-repeat;
background-size: 1em auto;
padding-left: 40px;
font-size: 24px;
margin: 1rem 0;
}
Efekt widać poniżej.

Podsumowanie
SVG w połączeniu z CSS-em daje więcej możliwości budowania elastycznych, adaptacyjnych dokumentów. Wiesz już, jak:
- stylować elementy SVG CSS-em.
- animować właściwości SVG,
- używać media queries i API
matchMedia, żeby pokazywać i ukrywać części dokumentu SVG.


