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ć?


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.

<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