PerfectVector
Autor: Irene Kim9 min czytania

SVG preserveAspectRatio: dopasuj grafikę bez rozciągania

Wybierz meet, slice lub none do dopasowania SVG. Sprawdź wyrównanie, przycinanie i puste płótno na jednym emblemacie oraz rozróżnij mapowanie SVG i właściwość CSS object-fit.

Na tej stronie

Użyj preserveAspectRatio="xMidYMid meet", gdy cały viewBox SVG ma się zmieścić w obszarze wyświetlania bez rozciągania. Użyj slice, gdy ten obszar musi zostać pokryty, a część zawartości może wystawać poza jego krawędzie. Używaj none tylko wtedy, gdy celowo chcesz zastosować różne skale w poziomie i w pionie.

Najważniejsze jest rozróżnienie między prostokątem współrzędnych grafiki, określonym przez viewBox, a obszarem wyświetlania, w którym grafika się pojawia. Dopasowanie zmienia sposób mapowania jednego na drugi. Nie przerysowuje logo, nie usuwa pustego płótna źródłowego ani nie usuwa trwale przyciętych ścieżek.

Najpierw wybierz sposób dopasowania

CelWartość atrybutuKompromis przy różnych proporcjach
Pokaż cały viewBoxxMidYMid meetWzdłuż jednej osi pozostaje niewykorzystana przestrzeń
Pokryj obszar wyświetlaniaxMidYMid sliceCzęść viewBox wystaje poza obszar wyświetlania
Wypełnij obszar, stosując niezależne skale osinoneKoła mogą się odkształcić, a proporcje innych kształtów mogą zostać zaburzone

Dokumentacja MDN preserveAspectRatio reference opisuje te wartości oraz wartość domyślną, xMidYMid meet. W przypadku elementu svg takie mapowanie wymaga viewBox. W nazwie atrybutu wielkość liter ma znaczenie: zachowaj wielkie A i R.

W przypadku logo zacznij od meet. Utrata litery lub zmiana koła w owal zwykle daje gorszy rezultat niż pozostawienie odrobiny wolnej przestrzeni. W przypadku ozdobnego tła celowe przycięcie może być dopuszczalne. Zdecyduj o tym, zanim wybierzesz wyrównanie.

Schematyczne porównanie całego emblematu, przyciętego powiększonego emblematu i rozciągniętego emblematu wewnątrz ramek
Ilustracja trzech sposobów dopasowania: zachowanie całej kompozycji, pokrycie ramki z przycięciem lub dopuszczenie zniekształcenia. Poniższe pomiary w przeglądarce wykorzystują osobny, autorski przykład testowy SVG.

Przetestuj jeden emblemat w obszarach wyświetlania o dwóch różnych kształtach

Ten autorski przykład wykorzystuje koło, prostokąt i trójkąt przesunięty względem środka. Koło uwidacznia rozciąganie, a różniące się od siebie elementy ułatwiają zauważenie zmian wyrównania w porównaniu z symetryczną odznaką.

Wklej ten kod do pliku HTML i otwórz go w przeglądarce:

<svg width="300" height="100" viewBox="0 0 200 100"
     preserveAspectRatio="xMidYMid meet"
     xmlns="http://www.w3.org/2000/svg"
     role="img" aria-label="Circle, rectangle, and triangle emblem"
     style="background:#f4ead4; overflow:hidden">
  <circle cx="40" cy="50" r="25" fill="#147d78" />
  <path d="M85 20 H130 V80 H85Z" fill="#e5a340" />
  <path d="M145 70 L170 25 L190 70Z" fill="#183549" />
</svg>

ViewBox ma szerokość 200 jednostek i wysokość 100 jednostek. Jego proporcje wynoszą 2:1. Pierwszy obszar wyświetlania ma 300 na 100 pikseli CSS, czyli proporcje 3:1. Zmień tylko atrybut, aby porównać xMidYMid slice i none. Następnie zmień obszar wyświetlania na width="100" height="300" i powtórz test.

Wyrenderowaliśmy tę geometrię w Chrome za pomocą niewielkiego skryptu testowego opartego na selektorach. Odczyt wykorzystywał bieżącą macierz transformacji grupy zawierającej grafikę. Uzyskane skale i przesunięcia odpowiadały poniższym wartościom; przesunięcie dla slice wynoszące około −25 pikseli zostało tu zaokrąglone.

Obszar wyświetlaniaUstawienieSkala pozioma / pionowaPrzesunięcie przy wyśrodkowaniu w pikselach obszaru wyświetlania
300 × 100meet1 / 150 w poziomie, 0 w pionie
300 × 100slice1.5 / 1.50 w poziomie, −25 w pionie
300 × 100none1.5 / 10 / 0
100 × 300meet0.5 / 0.50 w poziomie, 125 w pionie
100 × 300slice3 / 3−250 w poziomie, 0 w pionie
100 × 300none0.5 / 30 / 0

W wysokim obszarze wyświetlania meet pokazało wszystkie trzy małe kształty. Wyśrodkowane slice pokazało tylko część powiększonej kompozycji, zdominowaną przez złoty prostokąt. none sprawiło, że koło stało się wąskie i wysokie. To sprawdzenie tego przykładu testowego w Chrome, a nie gwarancja zachowania podczas importu w każdym edytorze graficznym.

Reguła skalowania jest prosta w tym przykładzie, w którym początek viewBox znajduje się w punkcie zerowym. Podziel szerokość obszaru wyświetlania przez szerokość viewBox, a następnie wysokość obszaru wyświetlania przez wysokość viewBox. meet używa mniejszego ilorazu dla obu osi, a slice — większego. none zachowuje oba ilorazy osobno. SVG coordinate-system specification definiuje to mapowanie, w tym wyrównanie oraz niezerowe współrzędne początku viewBox.

Użyj wyrównania, aby zdecydować, gdzie znajdzie się wolna przestrzeń

Pierwsze słowo kluczowe określa wyrównanie. xMin, xMid i xMax wyrównują odpowiednio lewą krawędź, środek w poziomie lub prawą krawędź viewBox. YMin, YMid i YMax robią to samo w pionie. Odnoszą się one do prostokąta viewBox, który może zawierać pustą przestrzeń wokół samych ścieżek.

W wysokim testowym obszarze wyświetlania:

  • xMinYMin meet umieszcza dopasowany viewBox u góry zamiast wyśrodkowywać go w pionie.
  • xMinYMin slice utrzymuje wyrównanie lewej strony viewBox z lewą stroną obszaru wyświetlania. Powiększona prawa strona wystaje poza obszar wyświetlania.
  • xMidYMid slice rozkłada zawartość wystającą w poziomie na obie strony.

W skrypcie testowym zmieniliśmy wyśrodkowanie na xMinYMin. Przesunięcia zarówno dla meet, jak i slice wyniosły wtedy zero, a ich współczynniki skali pozostały równe odpowiednio 0.5 i 3. Wyrównanie przesunęło kompozycję; nie zmieniło skali dopasowania.

Zmiana wyrównania jest widoczna tylko na osi, na której pozostaje wolna przestrzeń lub zawartość wystaje poza obszar. W szerokim wariancie z meet viewBox już wypełnia całą wysokość, więc zmiana YMid na YMin nie powoduje przesunięcia w pionie — nie ma na nie miejsca.

Świadomie zdecyduj o przycinaniu

slice wybiera skalę. Przycinanie określa, czy widzisz części wystające poza obszar wyświetlania. Przykład jawnie ustawia overflow:hidden, aby przycięcie było przewidywalne.

W skrypcie testowym z wysokim obszarem wyświetlania zmiana overflow na visible ujawniła powiększone koło i trójkąt poza obszarem wyświetlania z ustawieniem slice. Geometria nie zniknęła. Dokumentacja MDN SVG overflow reference wyjaśnia zależność między overflow a przycinaniem do obszaru wyświetlania, w tym różnice w domyślnych stylach w różnych kontekstach SVG.

Nie traktuj slice jako operacji przycinania ścieżek. Jeśli plik przeznaczony do przekazania ma zawierać tylko zachowaną geometrię, wykonaj i zweryfikuj rzeczywistą operację edycji. W przypadku niestandardowego, nieprostokątnego okna wyświetlania odpowiednim narzędziem może być clipPath.

Podobnie meet gwarantuje, że viewBox się zmieści; nie może zagwarantować, że zmieści się cała narysowana zawartość. Obrys, filtr lub ścieżka poza tym prostokątem źródłowym nadal mogą wystawać poza niego. Sprawdź widoczne krawędzie, zamiast polegać wyłącznie na atrybucie.

Popraw pustą przestrzeń w źródle, zanim zaczniesz walczyć z wyrównaniem

Załóżmy, że mały znak zajmuje tylko środek bardzo dużego viewBox. meet dopasowuje cały ten prostokąt współrzędnych, wraz z pustymi marginesami. Wynik może wyglądać na zbyt mały, nawet jeśli skalowanie jest prawidłowe.

Sprawdź eksportowane płótno lub obszar roboczy w edytorze. Jeśli zmienisz viewBox, aby ciaśniej objąć kompozycję, uwzględnij zamierzone obrysy i efekty oraz ponownie sprawdź każde umieszczenie grafiki. Nie usuwaj automatycznie wszystkich marginesów: źródło może zawierać celowo pozostawioną wolną przestrzeń wokół znaku marki.

Problemy z rozmiarem fizycznym to osobna kwestia. SVG, który importuje się z niewłaściwym rozmiarem w milimetrach, wymaga zastosowania procedury ustalania rozmiaru SVG; zmiana wyrównania przy dopasowaniu raczej nie rozwiąże problemu z przyjętymi jednostkami.

Rozróżniaj osadzone SVG i dopasowanie obrazu

W przypadku SVG osadzonego bezpośrednio w HTML zmień atrybut odpowiedniego elementu svg. CSS może określać rozmiar pola tego elementu, a preserveAspectRatio mapuje jego viewBox do tego pola.

W przypadku zewnętrznego SVG użytego w elemencie obrazu HTML CSS steruje dopasowaniem obrazu będącego zawartością zastępowaną:

<img class="brand-mark" src="emblem.svg" alt="Brand emblem">
<style>
  .brand-mark {
    width: 300px;
    height: 100px;
    object-fit: contain;
    object-position: center;
  }
</style>

Dokumentacja MDN object-fit documentation opisuje, jak zawartość zastępowana dopasowuje się do swojego pola CSS. To inna warstwa niż edycja wewnętrznego mapowania dokumentu SVG. object-fit: contain również nie usuwa pustego płótna już obecnego w źródle. Przy wyborze sposobu osadzenia zapoznaj się z porównaniem SVG osadzonego bezpośrednio w HTML i elementu obrazu.

Istnieje również element SVG image, zapisywany pełnym słowem zamiast HTML-owego img. Jego preserveAspectRatio steruje tym, jak wskazany obraz dopasowuje się do prostokąta ustalonego dla tego elementu. Jest to wyjątek od ogólnego wymogu podania viewBox w tym samym elemencie, co wyjaśnia dokumentacja atrybutu w MDN. Rozróżnienie tych trzech przypadków pozwala uniknąć prób naprawiania obrazu HTML przez dodanie do niego atrybutu przeznaczonego wyłącznie dla SVG.

Zachowaj proporcje źródła przed umieszczeniem grafiki

Jeśli masz tylko PNG lub JPG własnego znaku i potrzebujesz edytowalnej geometrii wektorowej, PerfectVector może odtworzyć źródło SVG, zanim zbudujesz układ. Najpierw sprawdź kontury, małe otwory i granice płótna. Dopasowanie wyniku zachowuje jego obecną geometrię; nie może naprawić zniekształconego źródła ani odtworzyć szczegółów, których wcześniej nie udało się odzyskać.

Jeśli masz już poprawny plik SVG, możesz od razu sprawdzić jego dopasowanie. W przypadku prostego emblematu powyżej wystarczy ręcznie zapisana geometria. Omówienie wektoryzacji obrazów wyjaśnia, kiedy przydatne jest odtwarzanie ścieżek z obrazu rastrowego.

Jeśli masz znak wyłącznie w postaci rastrowej, wypróbuj swój plik źródłowy w PerfectVector, sprawdź SVG, a następnie porównaj umieszczenie w szerokim i wysokim obszarze z meet, zanim rozważysz przycięcie. Zachowaj oryginalny wzorcowy plik wektorowy, aby decyzje dotyczące układu pozostawały odwracalne.

Często zadawane pytania

Dlaczego mój SVG nadal ma pustą przestrzeń przy ustawieniu meet? Obszar wyświetlania i viewBox mogą mieć różne proporcje, przez co po równomiernym skalowaniu pozostaje wolna przestrzeń. Źródłowy viewBox może też zawierać marginesy wokół ścieżek. Wyrównanie przesuwa ten prostokąt; nie usuwa pustej przestrzeni w jego wnętrzu.

Czy slice trwale przycina grafikę? Nie. Zmienia skalę używaną do pokrycia obszaru wyświetlania. Overflow i przycinanie sterują tym, które części są widoczne. Oryginalna geometria ścieżek pozostaje w dokumencie, chyba że edytujesz ją osobno.

Dlaczego none zmienia moje koło w owal? Dopuszcza różne współczynniki skali w poziomie i w pionie. Gdy proporcje obszaru wyświetlania i viewBox się różnią, koło może stać się elipsą. Użyj meet lub slice ze słowem kluczowym określającym wyrównanie, aby zachować równomierne skalowanie.

Źródła

  1. MDN preserveAspectRatio — Definiuje wartości dopasowania, wyrównanie, wartości domyślne i wyjątek dotyczący elementu SVG image.
  2. SVG coordinate-system specification — Definiuje obliczanie skali i przesunięcia dla obszaru wyświetlania.
  3. MDN SVG overflow — Wyjaśnia, jak overflow steruje przycinaniem do obszaru wyświetlania.
  4. MDN object-fit — Opisuje dopasowanie zastępowanej zawartości obrazu do pola CSS.

Więcej z bloga

Zacznij od czystszego SVG,
który łatwiej edytować