Kod zamiast grafiki: Kompletny przewodnik po Inline SVG w czystym HTML
W dzisiejszym web developmencie panuje niepokojąca tendencja do przekombinowywania prostych rzeczy. Potrzebujesz trzech ikon na krzyż? Wielu programistów automatycznie instaluje potężne biblioteki (np. FontAwesome), ładuje zewnętrzne skrypty CDN albo – co gorsza – wrzuca ciężkie pliki PNG. Efekt? Strona puchnie, wykonuje dodatkowe zapytania sieciowe, a nad estetyką i tak trudno w pełni zapanować.
A przecież nowoczesne przeglądarki mają już wszystko, czego nam trzeba. Rozwiązaniem jest Inline SVG – czyli czysty kod wektorowy wklejony bezpośrednio w strukturę HTML.
W tym przewodniku odczarujemy format SVG. Przejdziemy od absolutnych podstaw matematyki wektorowej, przez gotowe przykłady przydatnych ikon, aż po zaawansowaną stylizację za pomocą CSS i kwestie bezpieczeństwa.
Czym tak naprawdę jest SVG
SVG (Scalable Vector Graphics) to nie jest klasyczny plik graficzny złożony z pikseli (jak JPG czy PNG). To dokument tekstowy oparty na strukturze XML. Kiedy osadzasz go na stronie, przeglądarka nie musi dekodować obrazu – ona po prostu czyta instrukcje matematyczne i rysuje kształty w locie.
Dzięki temu grafika wektorowa ma jedną potężną zaletę: jest nieskończenie skalowalna. Możesz rozciągnąć ikonę do rozmiaru ekranu kinowego, a jej krawędzie pozostaną idealnie ostre. Jej rozmiar to przy tym zaledwie kilkaset bajtów.
Anatomia podstawowego znacznika SVG
Przyjrzyjmy się bazowej strukturze, która tworzy przestrzeń dla naszej grafiki:
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> </svg>
| viewBox="0 0 24 24" | To absolutnie kluczowy atrybut. Definiuje wewnętrzną siatkę współrzędnych (nasz wirtualny arkusz papieru). Pierwsze dwie cyfry (0 0) to punkt początkowy (lewy górny róg), a kolejne dwie (24 24) to szerokość i wysokość tej przestrzeni roboczej. Niezależnie od tego, jak duża fizycznie będzie ikona na ekranie, wszystkie kształty wewnątrz rysujemy w skali od 0 do 24. |
| fill="none" | Informuje przeglądarkę, że domyślnie nie chcemy wypełniać kolorem wnętrza rysowanych obiektów. |
| stroke="currentColor" | Nasza tajna broń w CSS (o niej za chwilę). Definiuje kolor linii. |
| stroke-width="2" | Określa grubość linii w jednostkach naszego viewBox. |
Praktyczny zestaw ikon: Zobacz, jakie to proste
Najważniejszym elementem wewnątrz SVG jest znacznik <path> (ścieżka). Jego sercem jest atrybut d (data), który zawiera instrukcje dla wirtualnego pióra. Zamiast skomplikowanych teorii, zobaczmy to na żywych, gotowych do użycia przykładach.
Absolutny fundament – pojedyncza linia (pozioma i pionowa)
Zanim przejdziemy do skomplikowanych kształtów, zobaczmy, jak narysować najbardziej surowy element grafiki wektorowej przy użyciu znacznika <line>. To najlepszy sposób, aby zrozumieć, jak działa siatka współrzędnych viewBox.
Linia pozioma (Horizontal Line):
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
<line x1="4" y1="12" x2="20" y2="12"></line>
</svg>
Linia pozioma - Podgląd SVG
Linia pionowa (Vertical Line):
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
<line x1="12" y1="4" x2="12" y2="20"></line>
</svg>
Linia pionowa - Podgląd SVG
Jak to czytać?
- Znacznik <line> potrzebuje tylko dwóch punktów: startowego (x1, y1) oraz końcowego (x2, y2).
- W przypadku linii poziomej, wartość Y pozostaje niezmienna (12), a rysik przesuwa się od X=4 do X=20.
- W przypadku linii pionowej, stała jest wartość X (12), podczas gdy linia biegnie w dół od Y=4 do Y=20.
- Dodanie stroke-linecap="round" sprawia, że końce tych prostych odcinków są estetycznie zaokrąglone, a nie ostro ścięte.
Przykład 1: Klasyczna strzałka w prawo (np. do linków "Więcej")
<svg class="link-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="5" y1="12" x2="19" y2="12"> </line>
<polyline points="12 5 19 12 12 19"> </polyline>
</svg>
Idealna ikona do dynamicznych odnośników tekstowych. Podgląd SVG
Jak to działa? Zamiast jednej skomplikowanej ścieżki użyliśmy tu czytelnych sub-znaczników: <line> rysuje prostą poziomą linię od punktu X=5 do X=19 na wysokości Y=12. Z kolei <polyline> tworzy załamany grot strzałki łączący trzy punkty. Atrybuty stroke-linecap="round" dbają o to, by końcówki linii były estetycznie zaokrąglone.
Przykład 2: Minimalistyczna strzałka narożna (skos w górę-prawo)
<svg class="link-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="7" y1="17" x2="17" y2="7"></line>
<polyline points="7 7 17 7 17 17"></polyline>
</svg>
Niezastąpiona przy linkach prowadzących na zewnętrzne portale lub projekty. Podgląd SVG
Przykład 3: Ikona listu / koperty (np. do zapisu na Newsletter)
<svg class="link-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path>
<polyline points="22,6 12,13 2,6"></polyline>
</svg>
Doskonale sprawdza się przy formularzach kontaktowych i modułach subskrypcji. Podgląd SVG
Wskazówka: Tutaj litera `M` w ścieżce oznacza Move to (podnieś pióro i skocz do współrzędnych), a litera `h` to horizontal line (rysuj linię poziomą). Na końcu `z` zamyka automatycznie cały kształt, tworząc ramkę koperty.
Przykład 4: Ikona informacyjna / uwaga (i)
<svg class="link-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="10"></circle>
<line x1="12" y1="16" x2="12" y2="12"></line>
<line x1="12" y1="8" x2="12.01" y2="8"></line>
</svg>
Przydatna przy wszelkiego rodzaju komunikatach lub bocznych notatkach. Podgląd SVG
Przykład: Geometryczne logo "K"
Jak wykorzystać zdobytą wiedzę do stworzenia czegoś unikalnego? Zamiast rysować skomplikowane krzywe, minimalistyczne logo marki możemy zbudować z zaledwie trzech prostych linii i jednego punktu w przestrzeni 100 x 100.
- viewBox="0 0 100 100" – Zwiększyliśmy obszar roboczy, aby precyzyjniej rozłożyć proporcje litery.
- Konstrukcja: Pierwsza linia (<line>) tworzy stabilny pionowy filar struktury. Druga i trzecia linia precyzyjnie łączą się pod kątem, tworząc ramiona litery K.
- Element „Ma” (Negatywna Przestrzeń): Samotny punkt <circle> po prawej stronie domyka kompozycję optycznie, wprowadzając do projektu oddech i harmonię, tak ważną w japońskim minimalizmie.
- Dzięki stroke="currentColor", wrzucając to logo na ciemną stronę, automatycznie dopasuje się ono do jasnego tekstu, a na jasnej – stanie się ciemne.
<svg class="link-icon" viewBox="0 0 100 100" fill="none" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round">
<line x1="35" y1="20" x2="35" y2="80"></line>
<line x1="35" y1="50" x2="65" y2="20"></line>
<line x1="47" y1="38" x2="65" y2="80"></line>
<circle cx="70" cy="50" r="1" fill="currentColor" stroke="none"></circle>
</svg>
Podgląd SVG
Przykład: BOT
<svg xmlns="http://www.w3.org/2000/svg" class="link-icon" viewBox="0 0 24 24" width="100%" height="100%">
<defs>
<linearGradient id="botGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#4a5568" stop-opacity="0.8"/>
<stop offset="100%" stop-color="#1a202c" stop-opacity="0.9"/>
</linearGradient>
</defs>
<path d="M6 9V6h2M18 9V6h-2" stroke="#4fd1c5" stroke-width="2" stroke-linecap="round" fill="none"/>
<rect x="4" y="8" width="16" height="11" rx="3" fill="url(#botGrad)" stroke="#718096" stroke-width="1.5"/>
<circle cx="9" cy="13" r="1.5" fill="#4fd1c5"/>
<circle cx="15" cy="13" r="1.5" fill="#4fd1c5"/>
<path d="M8 16h8" stroke="#4fd1c5" stroke-width="1.5" stroke-linecap="round"/>
</svg>
Podgląd SVG
Magia integracji: currentColor i CSS
Największa przewaga wklejania kodu SVG bezpośrednio do HTML (czyli właśnie inline) objawia się w momencie, gdy chcemy zmienić jego wygląd za pomocą CSS.
Gdybyś załadował obrazek przez <img src="ikona.png">, zmiana jego koloru przy najechaniu myszką wymagałaby podmieniania plików albo stosowania karkołomnych filtrów CSS. W przypadku Inline SVG ten problem nie istnieje.
Dzięki temu, że w strukturze ikony wpisaliśmy stroke="currentColor", ikona zachowuje się jak zwykła czcionka. Automatycznie przejmuje kolor tekstu rodzica.
Zobacz, jak elegancko możemy ostylować link z ikoną w naszym pliku CSS:
/* Bazowe ustawienia dla wszystkich naszych ikon */
.link-icon {
width: 1.25rem;
height: 1.25rem;
vertical-align: middle;
transition: stroke-width 0.2s ease, transform 0.2s ease;
}
/* Stylizacja odnośnika */
.stylish-link {
color: #a0aec0; /* Stonowany szary */
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 0.5rem; /* Odstęp między tekstem a ikoną */
transition: color 0.2s ease;
}
/* Efekt po najechaniu myszką */
.stylish-link:hover {
color: #3182ce; /* Zmiana koloru tekstu... i ikony jednocześnie! */
}
.stylish-link:hover .link-icon {
transform: translateX(3px); /* Delikatne przesunięcie strzałki w prawo */
stroke-width: 2.5; /* Pogrubienie linii ikony na hoverze! */
}
Zwróć uwagę na elastyczność: za pomocą jednej pseudo-klasy :hover zmieniamy kolor tekstu, kolor ikony, przesuwamy ją o 3 piksele i dynamicznie pogrubiamy jej linie z 2 na 2.5. Żaden tradycyjny format graficzny tego nie potrafi.
Anatomia optymalizacji, czyli jak odchudzić kod SVG
Gdy eksportujesz grafikę z programów takich jak Adobe Illustrator, Inkscape czy Figma, wygenerowany kod SVG jest często niepotrzebnie przeładowany. Zawiera mnóstwo zbędnych metadanych, tagów edytorskich, identyfikatorów warstw, a nawet osadzonych stylów i przestrzeni nazw XML. W efekcie ikona, która powinna mieć rozmiar zaledwie 400 bajtów, potrafi zajmować kilkanaście kilobajtów.
Dla technicznego minimalisty to niedopuszczalne. Aby wycisnąć z kodu maksimum wydajności, musimy przeprowadzić proces tzw. minifikacji i czyszczenia. Polega on na ręcznym usuwaniu znaczników <metadata>, zamianie skomplikowanych i długich ścieżek path na proste kształty geometryczne (takie jak <circle> czy <line>) oraz zaokrąglaniu współrzędnych punktów do liczb całkowitych. Narzędzia automatyczne (np. SVGO) robią to świetnie, ale to precyzyjne, ręczne oczyszczenie kodu z poziomu edytora tekstowego daje pełną kontrolę i gwarantuje, że na produkcję trafia wyłącznie czysta, lekka matematyka wektorowa.
Bezpieczeństwo SVG: O czym musisz wiedzieć
Skoro SVG to czysty kod tekstowy, to czy niesie za sobą ryzyko? Tak, ponieważ struktura XML pozwala na osadzanie zewnętrznych zasobów, stylów, a nawet skryptów JavaScript (<script>). Oznacza to potencjalne ryzyko ataków typu XSS (Cross-Site Scripting).
Obowiązuje tu jednak prosta i bezpieczna zasada:
| Gdy sam kontrolujesz kod źródłowy (Inline SVG) | Jest to w 100% bezpieczne. Widzisz każdą linię geometrii wejściowej. Nikt nie wstrzyknie złośliwego kodu do statycznego pliku HTML, który sam edytujesz i wrzucasz na serwer. |
| Gdy pozwalasz użytkownikom wgrywać pliki (np. awatary) | To ogromne zagrożenie. Użytkownik mógłby przesłać plik avatar.svg, w którym zaszyty jest skrypt wykradający pliki cookies. Takie pliki przed wyświetleniem trzeba bezwzględnie przepuścić przez tzw. sanitizer (np. narzędzie DOMPurify). |
Twoja tarcza: Content Security Policy (CSP)
Jeśli prowadzisz witrynę dbającą o najwyższe standardy bezpieczeństwa, Twoją główną linią obrony są nagłówki serwera, a w szczególności rygorystyczna polityka Content Security Policy. Odpowiednio skonfigurowane CSP blokuje wykonywanie nieautoryzowanych skryptów inline. Nawet jeśli w jakimś pliku XML znalazłby się złośliwy skrypt, przeglądarka odmówi jego uruchomienia, chroniąc użytkowników.
Dlaczego nie warto zastępować SVG emotikonami
Może pojawić się pokusa: „Po co pisać te linie kodu, skoro mogę wstawić gotową emotkę ➡️ albo ✉️?”.
Emotikony oparte na standardzie Unicode są świetne do luźnych wiadomości, ale w profesjonalnym i minimalistycznym designie mają ogromną wadę: całkowity brak powtarzalności.
Każdy system operacyjny i każda przeglądarka renderuje emotikony według własnego zestawu grafik. Na Twoim komputerze strzałka może być cienka i minimalistyczna, na macOS zmieni się w błyszczący, trójwymiarowy obiekt, a na Androidzie zyska jaskrawożółte tło. Taki chaos potrafi całkowicie zniszczyć zaplanowaną kompozycję i estetykę strony.
Inline SVG gwarantuje, że Twoja ikona będzie wyglądać identycznie na każdym ekranie świata – bez względu na to, czy użytkownik otwiera stronę na starym telefonie, czy nowoczesnym monitorze 4K.
Podsumowanie
Techniczny minimalizm to nie ślepe odrzucanie nowoczesności i powrót do ery czystego tekstu. To sztuka osiągania doskonałej estetyki za pomocą najbardziej surowych, wydajnych i niezależnych narzędzi.
Czysty HTML z kilkoma liniami kodu Inline SVG daje Ci pełną niezależność od zewnętrznych dostawców, redukuje wagę strony do absolutnego minimum i zapewnia doskonałe bezpieczeństwo. Czas wyrzucić ciężkie paczki ikon i zacząć pisać grafikę ręcznie.
👇
▒ Przewodnik po blogu: wszystkie posty o programowaniu w jednym miejscu. ▹ Zobacz