Lekcja 9. Gradienty i wzory

wrz 3, 2026 | Kurs SVG

Wypełnienia, które są osobnymi obiektami

Do tej pory fill przyjmował kolor. Teraz przyjmie coś zupełnie innego — odwołanie do obiektu zdefiniowanego gdzie indziej w pliku.

To jest zmiana sposobu myślenia, nie tylko nowa składnia. Gradient nie jest wartością koloru. Jest bytem, który leży w <defs> i ma własne id. Kształt tylko mówi „wypełnij mnie tamtym", a jeden gradient może obsłużyć dziesięć figur naraz.

Anatomia

html

<defs>
  <linearGradient id="zachod">
    <stop offset="0%" stop-color="#e05c1a"/>
    <stop offset="100%" stop-color="#0f0f0f"/>
  </linearGradient>
</defs>

<rect fill="url(#zachod)" .../>

Trzy elementy układanki. <defs> to schowek — wszystko, co w nim leży, nie jest rysowane, tylko czeka na wywołanie. <stop> to punkt na osi gradientu: offset mówi gdzie (od 0% do 100%), stop-color jakim kolorem, a opcjonalne stop-opacity z jaką przezroczystością. url(#id) to odwołanie.

Punktów zatrzymania może być dowolnie wiele i nie muszą być rozłożone równo. Dwa <stop> o tym samym offset dają ostrą granicę zamiast przejścia — tak robi się paski i flagi bez rysowania osobnych prostokątów.

Kierunek

html

<linearGradient id="g" x1="0" y1="0" x2="1" y2="0">

Cztery liczby wyznaczają oś, wzdłuż której biegnie przejście: od punktu początkowego do końcowego. Domyślnie jest to lewa krawędź do prawej.

Suwaki zmieniają wektor kierunku i pozycję środkowego punktu zatrzymania. Ustaw y2 na 1 przy x2 równym 0, a gradient pójdzie z góry na dół. Oba na 1 — po przekątnej.

Zwróć uwagę, że te liczby są ułamkami, nie jednostkami. To dlatego, że domyślnie gradient działa w objectBoundingBox— układzie, w którym 0 to jedna krawędź kształtu, a 1 druga, niezależnie od jego prawdziwego rozmiaru.

Ma to ogromną zaletę: ten sam gradient wygląda tak samo na małej ikonie i na wielkim tle. I jedną wadę, o której warto wiedzieć zawczasu.

Pułapka: układ współrzędnych gradientu

Skoro układ jest przywiązany do prostokąta otaczającego kształt, to gradient rozciąga się razem z nim. Zastosowany do wąskiego, wysokiego prostokąta zostanie spłaszczony w poziomie. Zastosowany do kilku figur o różnych proporcjach będzie w każdej wyglądał inaczej, choć definicja jest jedna.

Gdy potrzebujesz, żeby gradient był położony w konkretnym miejscu płótna — a nie względem kształtu — przełącz go:

html

<linearGradient id="g" gradientUnits="userSpaceOnUse"
                x1="0" y1="0" x2="200" y2="0">

Teraz liczby są zwykłymi jednostkami użytkownika, takimi jak w viewBox. Dzięki temu kilka osobnych kształtów może dzielić jedno wspólne przejście kolorów, tak jakby były wycięte z jednego tła. To standardowy trik przy ikonach składających się z kilku części.

Warto też znać spreadMethod. Domyślne pad przedłuża skrajne kolory poza oś gradientu. reflect odbija wzór tam i z powrotem, repeat powtarza go od nowa — obie wartości działają dopiero wtedy, gdy oś gradientu jest krótsza niż kształt.

Gradient promienisty

html

<radialGradient id="kula" cx="0.5" cy="0.5" r="0.6"
                fx="0.35" fy="0.3">

Zamiast osi mamy okrąg. cx i cy to jego środek, r promień. Do tego dochodzą fx i fy — ognisko, czyli punkt, z którego kolor faktycznie wychodzi.

Gdy ognisko pokrywa się ze środkiem, dostajesz równomierne koło. Gdy je odsuniesz, przejście robi się asymetryczne i figura zaczyna wyglądać jak kula oświetlona z boku.

Przesuń ognisko w lewy górny róg i zmniejsz promień. Płaskie koło zamienia się w bryłę — bez żadnego cienia, jednym gradientem. To najtańszy sposób na trójwymiarowość w płaskiej grafice.

Wzory

<pattern> działa jak gradient, tylko zamiast przejścia kolorów powtarza kafelek z dowolną zawartością. W środku może być cokolwiek: kształty, tekst, inny gradient, a nawet obrazek rastrowy.

html

<pattern id="kropki" width="22" height="22"
         patternUnits="userSpaceOnUse">
  <circle cx="10" cy="10" r="5" fill="#e05c1a"/>
</pattern>

Zmniejszaj kafelek. Przy rozmiarze poniżej piętnastu kropka zaczyna być przycinana, a poniżej dziesięciu znika zupełnie — bo jej środek wypada już poza kafelkiem. Wszystko, co wystaje poza kafelek, jest ucinane, a nie przenoszone do sąsiedniego.

To najczęstszy błąd przy wzorach: element narysowany w rogu kafelka wygląda na przecięty, bo jego druga połowa nie pojawia się po drugiej stronie. Żeby wzór ładnie się schodził na krawędziach, trzeba rysować go w kafelku dwukrotnie — raz w środku i raz przesunięty o pełny rozmiar kafelka.

Zwróć też uwagę na patternUnits="userSpaceOnUse". Bez tego rozmiar kafelka byłby ułamkiem wielkości figury, więc na dużym prostokącie kropki byłyby ogromne, a na małym mikroskopijne. Przy wzorach ustawienie na jednostki użytkownika jest niemal zawsze tym, o co Ci chodzi.

Pułapka, o której trzeba wiedzieć na stronie

Ta jest praktyczna i gryzie właśnie w WordPressie, gdzie na jednej stronie ląduje kilkanaście osadzonych SVG naraz.

Identyfikatory są wspólne dla całego dokumentu HTML, nie dla pojedynczego SVG. Jeśli dwie ikony mają wewnątrz gradient o id="g", druga z nich będzie odwoływać się do definicji z pierwszej. Ikona nagle zmienia kolor, choć nikt jej nie ruszał — a w pliku źródłowym wszystko jest w porządku.

Objaw jest charakterystyczny: grafika wygląda poprawnie w podglądzie i psuje się po wstawieniu na stronę. Zwykle łamie się dopiero ta druga, trzecia albo dziesiąta, w zależności od kolejności.

Lekarstwo jest proste: unikalne, opisowe identyfikatory w każdym pliku — ifox-hero-gradient, a nie a. Optymalizatory potrafią to zrobić automatycznie i wrócimy do tego w lekcji o SVGO.

Podsumowanie

  • Gradient i wzór to obiekty w <defs>, przywoływane przez url(#id).
  • <stop> ma offsetstop-color i stop-opacity; dwa stopy o tym samym offsecie dają ostrą granicę.
  • Domyślnie współrzędne gradientu są ułamkami rozmiaru kształtu, więc gradient rozciąga się razem z nim.
  • gradientUnits="userSpaceOnUse" przełącza na jednostki płótna i pozwala kilku kształtom dzielić jedno przejście.
  • W gradiencie promienistym fx/fy to ognisko — jego przesunięcie daje efekt bryły.
  • Zawartość wzoru jest przycinana do kafelka; nic nie przechodzi na sąsiedni.
  • Identyfikatory są wspólne dla całej strony — powtórzone id to najczęstsza przyczyna psujących się grafik po osadzeniu.

W następnej lekcji zajmiemy się ukrywaniem części obrazu: clipPath tnie po kształcie, mask po jasności, a różnica między nimi decyduje o tym, czy krawędź będzie ostra, czy miękka.


Do wypróbowania: w presecie pattern dopisz w kafelku drugi element — na przykład <rect width="{{w}}" height="1" fill="#f0ede6"/>. Dostaniesz kropki na liniowanym tle, a przy okazji zobaczysz, że wzór może zawierać dowolną liczbę kształtów, nie jeden.