pile·
프론트엔드·씨앤텍시스템즈씨앤텍시스템즈·

SVG를 이용하여 Animation 만들기_후속

SVG 를 HTML 에 넣을 때 자주 보이는 `preserveAspectRatio` 속성이 실제로 무엇을 결정하는지, viewBox 와 viewport 의 관계부터 정리한 글이다. meet 과 slice 두 값에 따라 정렬 키워드(xMin/xMid/xMax, YMin/YMid/YMax)가 어느 축에서만 효과를 갖는지를 그림 케이스로 하나씩 확인한다.

핵심 포인트
  • viewBox 는 SVG 가 가진 도형의 원형으로 Figma 에서 뽑은 frame 크기와 같은 값으로 잡히고, viewport 는 그 viewBox 를 들여다보는 "창문" 이다.
  • `preserveAspectRatio` 는 viewport 크기가 변할 때 viewBox 를 어떤 기준으로 맞출지 지정하는 속성이다.
  • slice 는 viewport 를 꽉 채우도록 비율을 맞추고 잘라내며, meet 은 원본 비율을 유지한 채 창문 안 위치를 정한다.
  • viewport 의 height 가 viewBox 보다 클 때 slice 를 쓰면 Y 좌표 키워드는 결과에 영향이 없고 X 좌표만 의미를 갖는다.
  • `none` 에 해당하는 케이스는 비율을 무시하고 viewport 크기에 viewBox 를 억지로 늘려 맞춘다.
상세 정리
  • 출발점: `<svg width="1440" height="2093" viewBox="0 0 1440 2093" preserveAspectRatio="xMinYMid meet">` 처럼 실제 마크업에서 마주치는 속성을 풀어 보는 것이 목적이다.
  • 기준 케이스: viewBox 가 200×200 이고 viewport 가 viewBox 와 같으면 아이콘이 원형 그대로 보인다. 여기서 두 크기를 어긋나게 만들며 관찰한다.
  • 실험 방법: `svg { border: 1px solid black; height: 100%; width: 200; }` 로 viewport 의 height 를 viewBox 의 height 보다 크게 만들고, 검정 테두리를 viewport 경계로 삼아 눈으로 비교한다.
  • slice 의 정의: viewport 의 height 가 더 클 때 viewport 의 height 를 기준으로 viewBox 비율을 맞춘 뒤, viewport 의 width 에 해당하는 위치를 x 좌표 키워드로 지정한다.
  • slice 케이스 비교: `xMinYMin slice`, `xMidYMid slice`, `xMaxYMax slice` 세 가지를 그림으로 놓고 보면 Y 값만 바꾼 `xMinYMax slice`, `xMidYMax slice` 가 같은 결과를 낸다 — Y 키워드가 무시된다는 뜻이다.
  • meet 의 정의: 같은 조건에서 meet 은 viewBox 의 원형 비율을 그대로 유지한 채 창문 안 어디에 놓을지를 y 좌표 키워드로 정한다. slice 와 유효 축이 반대다.
  • 반대 조건: viewport 의 height 가 viewBox 보다 작은 경우에는 meet 의 유효 축이 x 좌표로 바뀐다. 즉 어느 축이 남는지에 따라 정렬 키워드의 역할이 뒤집힌다.
  • 정리 관점: 속성값을 외우기보다 "어느 축이 넘치는가" 를 먼저 보고 meet/slice 를 고른 뒤 남는 축의 정렬만 지정하면 된다는 접근을 제시한다.
왜 읽나반응형 레이아웃에서 SVG 아이콘이 잘리거나 어긋날 때 원인을 짚고 싶은 프론트엔드 개발자·퍼블리셔에게 유용하다.
씨앤텍시스템즈
씨앤텍시스템즈 블로그
원문은 여기서 이어서 읽을 수 있어요
원문 읽기
읽음 (0)

이 글과 비슷한

  1. 프론트엔드·여기어때 (GC컴퍼니)여기어때 (GC컴퍼니)·

    항공 프론트엔드 구축기 (7/10): 창구를 하나만 두었습니다

    여기어때 항공 서비스 프론트엔드가 웹과 앱 웹뷰 두 환경에서 동일한 함수 호출로 동작하는 앱 브릿지 추상화 레이어를 설계한 과정을 다룬다. iOS·안드로이드 규약 차이와 "웹에 존재하지 않는 브릿지를 어떻게 호출하나"라는 문제를 단일 추상화 층으로 해결한 구현 사례다.

    요약 이어보기
    #react#typescript#webview+2