PerfectVector
작성: Irene Kim6분 읽기

SVG preserveAspectRatio: 늘어남 없이 그림 맞추기

SVG 맞춤에 meet, slice 또는 none을 선택하세요. 문양 하나로 정렬, 클리핑과 빈 캔버스를 테스트하고 SVG 매핑과 CSS object-fit을 구분합니다.

목차

전체 SVG viewBox가 늘어나지 않고 표시 영역 안에 들어가야 하면 preserveAspectRatio="xMidYMid meet"를 쓰세요. 영역을 덮어야 하고 일부 콘텐츠가 밖으로 나가도 되면 slice를 쓰세요. 가로·세로의 다른 배율이 의도된 경우에만 none을 쓰세요.

중요한 차이는 viewBox가 정의하는 그림 좌표 사각형과 표시되는 뷰포트입니다. 맞춤은 둘 사이 매핑을 바꿉니다. 로고를 다시 그리거나 원본 빈 캔버스를 제거하거나 잘린 경로를 영구 삭제하지 않습니다.

맞춤 동작부터 선택하기

목표속성 값비율이 다를 때의 절충
전체 viewBox 표시xMidYMid meet한 축에 사용하지 않는 공간
뷰포트 덮기xMidYMid sliceviewBox 일부가 뷰포트 밖으로 나감
축별 배율로 채우기none원과 다른 비율이 왜곡될 수 있음

MDN의 preserveAspectRatio 참고 문서는 값과 기본 xMidYMid meet를 설명합니다. svg 요소의 매핑에는 viewBox가 필요합니다. 속성은 대소문자를 구분하므로 대문자 A, R을 유지하세요.

로고는 meet부터 시작하세요. 글자 누락이나 원의 타원 변형은 보통 여백보다 나쁩니다. 장식 배경은 의도적인 자르기가 괜찮을 수 있습니다. 정렬 전에 결정하세요.

프레임 안의 완전한 문양, 잘린 확대 문양과 늘어난 문양의 개념 비교
전체 구성 보존, 자르기로 프레임 덮기와 왜곡 허용이라는 세 맞춤 선택의 일러스트입니다. 아래 브라우저 측정은 별도의 직접 만든 SVG 예제를 사용합니다.

두 뷰포트 모양에서 문양 하나 테스트하기

직접 만든 예제는 원, 사각형과 중심에서 벗어난 삼각형을 씁니다. 원은 늘어남을 드러내고 서로 다른 부분은 대칭 배지보다 정렬 변화를 알아보기 쉽게 합니다.

HTML 파일에 붙여 브라우저에서 여세요.

<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는 너비 200단위, 높이 100단위로 2:1입니다. 첫 뷰포트는 300 × 100 CSS 픽셀로 3:1입니다. 속성만 바꿔 xMidYMid slice와 none을 비교하세요. 이후 뷰포트를 width="100" height="300"으로 바꾸고 반복하세요.

작은 선택자 기반 테스트 도구로 Chrome에서 도형을 렌더링했습니다. 표시값은 그림 그룹의 현재 변환 행렬을 사용했습니다. 배율·이동은 다음과 같았으며 약 −25픽셀의 slice 오프셋은 반올림했습니다.

뷰포트설정가로 / 세로 배율뷰포트 픽셀의 중앙 이동
300 × 100meet1 / 1가로 50, 세로 0
300 × 100slice1.5 / 1.5가로 0, 세로 −25
300 × 100none1.5 / 10 / 0
100 × 300meet0.5 / 0.5가로 0, 세로 125
100 × 300slice3 / 3가로 −250, 세로 0
100 × 300none0.5 / 30 / 0

높은 뷰포트의 meet는 작은 도형 세 개를 모두 표시했습니다. 중앙 slice는 확대 구성 일부만 표시하고 금색 사각형이 대부분이었습니다. none은 원을 좁고 길게 만들었습니다. 이 예제의 Chrome 검사이며 모든 그래픽 편집기 가져오기를 보장하지는 않습니다.

원점 0 예제의 배율 규칙은 간단합니다. 뷰포트 너비를 viewBox 너비로, 높이를 viewBox 높이로 나눕니다. meet는 두 축에 작은 비율, slice는 큰 비율을 씁니다. none은 두 비율을 따로 유지합니다. SVG 좌표계 명세는 정렬과 0이 아닌 원점 포함 매핑을 정의합니다.

여유 공간 위치를 정렬로 선택하기

첫 키워드는 정렬을 제어합니다. xMin, xMid, xMax는 viewBox의 왼쪽, 가로 중앙과 오른쪽을 맞춥니다. YMin, YMid, YMax는 세로 대응입니다. 실제 경로 주변 여백을 포함할 수 있는 viewBox 사각형을 기준으로 합니다.

높은 테스트 뷰포트에서는 다음과 같습니다.

  • xMinYMin meet는 맞춘 viewBox를 세로 중앙 대신 위에 놓습니다.
  • xMinYMin slice는 viewBox 왼쪽을 뷰포트 왼쪽에 맞춥니다. 확대 오른쪽은 뷰포트 밖으로 나갑니다.
  • xMidYMid slice는 가로 넘침을 양쪽에 나눕니다.

테스트 도구를 중앙에서 xMinYMin으로 바꿨습니다. meet·slice 이동은 모두 0이 되고 배율은 각각 0.5와 3으로 유지됐습니다. 정렬은 구성을 옮기고 맞춤 배율은 바꾸지 않았습니다.

정렬 변화는 여유 공간이나 넘침이 있는 축에서만 보입니다. 넓은 meet는 이미 높이를 채우므로 YMid를 YMin으로 바꿔도 세로 이동 공간이 없습니다.

클리핑을 명시적으로 선택하기

slice는 배율을 선택합니다. 클리핑은 뷰포트 밖 부분의 표시 여부를 결정합니다. 예제는 자르기 예측이 가능하도록 overflow:hidden을 명시합니다.

높은 테스트에서 overflow를 visible로 바꾸면 slice 뷰포트 밖의 확대 원·삼각형이 보였습니다. 도형이 사라진 것이 아닙니다. MDN SVG overflow 참고 문서는 SVG 문맥별 기본 스타일 차이를 포함해 overflow·뷰포트 클리핑 관계를 설명합니다.

slice를 경로 잘라내기 연산으로 취급하지 마세요. 전달 파일에 남은 도형만 있어야 하면 실제 편집 연산을 수행·검증하세요. 비사각 사용자 지정 표시 창에는 clipPath가 적합할 수 있습니다.

마찬가지로 meet는 viewBox의 맞춤을 보장하지만 칠해진 모든 콘텐츠의 맞춤을 보장하지 않습니다. 스트로크, 필터나 원본 사각형 밖 경로는 여전히 넘칠 수 있습니다. 속성만 믿지 말고 보이는 가장자리를 확인하세요.

정렬과 씨름하기 전에 원본 여백 수정하기

매우 큰 viewBox 중앙만 작은 표식이 차지한다고 가정하세요. meet는 빈 여백을 포함한 전체 좌표 사각형을 맞춥니다. 배율이 올바라도 결과는 너무 작게 보일 수 있습니다.

편집기에서 내보낸 캔버스·아트보드를 확인하세요. 구성을 줄이려고 viewBox를 바꾸면 의도한 스트로크·효과를 포함하고 모든 배치를 다시 확인하세요. 모든 여백을 자동 제거하지 마세요. 브랜드 표식 주변에 의도한 보호 공간이 있을 수 있습니다.

물리 크기 문제는 별개입니다. 잘못된 mm 크기로 가져온 SVG에는 SVG 크기 작업 흐름이 필요합니다. 맞춤 정렬로 단위 가정이 고쳐질 가능성은 작습니다.

인라인 SVG와 이미지 맞춤 구분하기

인라인 SVG는 관련 svg 요소의 속성을 바꾸세요. CSS가 요소 상자의 크기를 정하고 preserveAspectRatio는 그 안에 viewBox를 매핑합니다.

HTML 이미지 요소의 외부 SVG는 CSS가 대체 이미지의 맞춤을 제어합니다.

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

MDN object-fit 문서는 대체 콘텐츠가 CSS 상자에 맞는 방법을 설명합니다. SVG 문서 내부 매핑 편집과 다른 계층입니다. object-fit: contain도 원본의 빈 캔버스를 제거하지 못합니다. 삽입 모델 선택은 인라인 SVG와 이미지 요소 비교를 참고하세요.

HTML img와 달리 단어 전체로 쓰는 SVG image 요소도 있습니다. 그 preserveAspectRatio는 참조 이미지를 해당 요소의 사각형에 맞춥니다. MDN 속성 문서가 설명하듯 같은 요소에 viewBox를 제공해야 하는 일반 요구의 예외입니다. 세 경우를 구분하면 HTML 이미지에 SVG 전용 속성을 추가해 고치려는 시도를 피합니다.

배치 전에 원본 비율 보존하기

사용자 표식이 PNG·JPG뿐이고 편집 벡터 도형이 필요하면 PerfectVector가 레이아웃 전에 SVG 소스를 복원할 수 있습니다. 윤곽선, 작은 구멍과 캔버스 경계부터 확인하세요. 맞춤은 현재 도형을 보존하며 왜곡 원본을 고치거나 복원되지 않은 세부를 다시 만들지 못합니다.

기존 깨끗한 SVG는 바로 맞춤 검사로 진행하세요. 위 단순 문양은 수동 작성 도형으로 충분합니다. 이미지 벡터화 개요는 래스터 경로 복원이 유용한 때를 설명합니다.

래스터 표식은 PerfectVector에서 원본을 시도하고 SVG를 확인하세요. 자르기를 고려하기 전에 meet로 넓고 높은 배치를 비교하세요. 레이아웃 결정을 되돌릴 수 있게 벡터 원본을 유지하세요.

FAQ

meet를 써도 SVG에 빈 공간이 있는 이유는 무엇인가요? 뷰포트·viewBox 비율이 다르면 균일 배율 후 여유 공간이 남습니다. 원본 viewBox에도 경로 주변 여백이 있을 수 있습니다. 정렬은 사각형을 이동하며 내부 여백을 제거하지 않습니다.

slice가 그림을 영구적으로 자르나요? 아닙니다. 뷰포트를 덮는 배율을 바꿉니다. Overflow·클리핑이 보이는 부분을 제어합니다. 별도 편집하지 않으면 원래 경로 도형은 문서에 남습니다.

none이 원을 타원으로 만드는 이유는 무엇인가요? 서로 다른 가로·세로 배율을 허용합니다. 뷰포트·viewBox 비율이 다르면 원이 타원이 됩니다. 균일 배율에는 정렬 키워드와 meet 또는 slice를 쓰세요.

Sources

  1. MDN preserveAspectRatio — 맞춤 값, 정렬, 기본값과 SVG image 예외를 정의합니다.
  2. SVG 좌표계 명세 — 뷰포트 배율·이동 계산을 정의합니다.
  3. MDN SVG overflow — overflow의 뷰포트 클리핑 제어를 설명합니다.
  4. MDN object-fit — CSS 상자 안 대체 이미지 콘텐츠 맞춤을 설명합니다.

블로그의 다른 글

편집하기 쉬운
더 깔끔한 SVG로 다시 시작하세요