웹 개발을 하다 보면 크게 래스터 이미지(Raster images)와 벡터 이미지(Vector images), 이 두 가지 유형의 이미지를 다루게 됩니다.
.bmp), PNG(.png), JPEG(.jpg), GIF(.gif) 같은 포맷들이 바로 래스터 이미지입니다.💡 강사의 팁: > 면접에서 종종 "래스터 이미지와 벡터 이미지의 차이가 무엇인가요?"라는 질문이 나옵니다. 이때 핵심 키워드는 '픽셀(해상도 의존적)'과 '수학적 계산(해상도 독립적)'입니다. 완벽하게 대답하실 수 있겠죠?
이 둘의 차이를 좀 더 쉽게 이해하기 위해 예시를 하나 살펴볼까요? 저희 GitHub 저장소에 있는 vector-versus-raster.html 라이브 예제를 확인해 보세요. 검은색 그림자가 있는 빨간색 별 이미지 두 개가 나란히 있는데, 겉보기엔 똑같아 보입니다. 하지만 왼쪽은 PNG(래스터) 파일이고, 오른쪽은 SVG(벡터) 이미지라는 차이가 있어요.
화면을 줌인(확대)해 보면 그 차이가 확연히 드러납니다. PNG 이미지는 각 픽셀의 위치와 색상 정보만 가지고 있기 때문에 확대를 하면 이미지가 깨져 보입니다(픽셀화 현상). 화면이 커지면서 하나의 픽셀이 화면의 여러 픽셀을 채우도록 크기가 커지기 때문에 이미지가 블록처럼 각져 보이는 거죠. 반면에, 벡터 이미지는 아무리 크기를 키워도 여전히 깔끔하고 선명하게 보입니다. 크기가 변하더라도 알고리즘이 이미지의 형태를 다시 계산해서 크기에 맞게 값을 조정해 주기 때문입니다.


📝 참고 (Note):
위에 보여드린 두 장의 이미지는 사실 모두 PNG 파일로 캡처된 것입니다. 왼쪽 별은 래스터 이미지를 렌더링한 모습이고, 오른쪽 별은 벡터 이미지를 렌더링한 모습을 보여주기 위해 캡처한 것이죠. 진짜 동작을 보시려면 꼭 vector-versus-raster.html 데모 페이지에 들어가서 직접 화면을 확대해 보세요!
뿐만 아니라, 벡터 이미지 파일은 래스터 이미지 파일보다 용량이 훨씬 가볍습니다. 이미지 안의 수많은 픽셀 정보를 하나하나 다 저장할 필요 없이, 몇 가지 알고리즘만 가지고 있으면 되기 때문이죠.
SVG는 벡터 이미지를 설명하기 위한 XML 기반의 언어입니다. HTML과 비슷한 마크업 언어라고 생각하시면 되는데, 차이점이 있다면 이미지에 나타내고 싶은 모양이나 적용하고 싶은 효과를 정의하기 위한 여러 가지 다양한 요소(elements)들을 가지고 있다는 점입니다. SVG는 콘텐츠가 아닌 '그래픽'을 마크업하기 위한 것이죠.
SVG는 <circle>(원)이나 <rect>(사각형) 같은 기본 도형을 만드는 요소뿐만 아니라, <path>나 <polygon>(다각형) 같은 더 복잡한 형태를 만드는 요소도 정의합니다. 더 나아가면 색상을 변환하는 <feColorMatrix>, 벡터 그래픽의 특정 부분에 애니메이션을 주는 <animate>, 그리고 이미지 위에 마스크를 씌우는 <mask>와 같은 고급 기능들도 사용할 수 있습니다.
아주 기본적인 예시로, 다음 코드는 원과 사각형을 만듭니다.
<svg
version="1.1"
baseProfile="full"
width="300"
height="200"
xmlns="[http://www.w3.org/2000/svg](http://www.w3.org/2000/svg)">
<rect width="100%" height="100%" fill="black" />
<circle cx="150" cy="100" r="90" fill="blue" />
</svg>
이 코드는 아래와 같은 결과를 만들어냅니다.

위 예제만 보면 '오, SVG 코드는 손으로 직접 짜기 쉽네?'라는 생각이 드실 수도 있습니다. 네, 간단한 SVG는 텍스트 편집기에서 직접 코딩할 수 있습니다. 하지만 이미지가 조금만 복잡해져도 손으로 코딩하는 건 금방 매우 어려워집니다. 그래서 보통 SVG 이미지를 만들 때는 Inkscape(잉크스케이프)나 Illustrator(어도비 일러스트레이터) 같은 벡터 그래픽 에디터 프로그램을 많이 사용합니다. 이런 프로그램들을 사용하면 다양한 그래픽 도구를 활용해 일러스트를 만들 수 있고, 사진을 벡터와 비슷하게 변환할 수도 있습니다(예: 잉크스케이프의 Trace Bitmap 기능).
지금까지 설명한 장점 외에도 SVG는 몇 가지 추가적인 장점이 있습니다.
그렇다면 왜 사람들은 여전히 SVG 대신 래스터 그래픽을 사용할까요? 당연히 SVG에도 단점이 존재하기 때문입니다.
위에서 설명한 이유들 때문에, 사진처럼 정밀하고 복잡한 이미지를 표현할 때는 SVG보다 래스터 그래픽(JPEG, PNG 등)이 훨씬 낫다고 할 수 있습니다.
💡 강사의 팁: > 잉크스케이프나 일러스트레이터 같은 에디터에서 내보낸(export) SVG 파일 안에는 불필요한 코드가 꽤 많이 포함되어 있습니다. 그래서 웹에 실제로 올리기 전에는 SVGO와 같은 SVG 최적화 도구를 사용해서 파일 용량을 한 번 줄여주는 것이 좋습니다.
이 섹션에서는 여러분의 웹 페이지에 SVG 벡터 그래픽을 추가할 수 있는 여러 가지 방법들을 살펴보겠습니다.
img 태그 사용하기 (The quick way: img element)<img> 요소를 통해 SVG를 포함시키려면, 일반 이미지를 넣을 때처럼 src 속성에 SVG 파일의 경로를 지정해 주면 됩니다. (다만, SVG 자체에 종횡비(aspect ratio) 정보가 없다면 height나 width 속성, 또는 둘 다 지정해 주어야 합니다.) 아직 읽어보지 않으셨다면 HTML images 문서를 먼저 읽어보시는 것을 권장합니다.
<img
src="equilateral.svg"
alt="triangle with all three sides equal"
height="87"
width="100" />
alt 속성을 이용해 텍스트 대체재를 쉽게 제공할 수 있습니다.<img> 태그를 <a> 태그로 감싸면 이미지를 아주 쉽게 하이퍼링크로 만들 수 있습니다.:focus와 같은 CSS 가상 클래스(pseudoclasses)를 사용해 이미지 스타일을 변경할 수 없습니다.SVG를 아예 지원하지 않는 아주 오래된 구형 브라우저(IE 8 이하, Android 2.3 이하)를 지원해야 한다면, src 속성에는 호환성을 위해 PNG나 JPG를 지정하고, srcset 속성(최신 브라우저만 인식함)에 SVG를 지정하는 방식을 사용할 수 있습니다. 이렇게 하면 SVG를 지원하는 최신 브라우저는 SVG를 로드하고, 구형 브라우저는 SVG를 무시한 채 PNG 이미지를 로드하게 됩니다.
<img
src="equilateral.png"
alt="triangle with equal sides"
srcset="equilateral.svg" />
아래 코드처럼 SVG를 CSS 백그라운드 이미지로 사용할 수도 있습니다. 이 경우에도 구형 브라우저는 자신이 이해할 수 있는 PNG를 띄우고, 최신 브라우저는 SVG를 불러옵니다.
background: url("fallback.png") no-repeat center;
background-image: url("image.svg");
background-size: contain;
앞서 설명한 <img> 태그 방식과 마찬가지로, CSS 백그라운드 이미지로 SVG를 삽입하면 JavaScript로 SVG를 제어할 수 없으며 CSS 조작에도 동일한 한계가 존재합니다.
만약 코드를 제대로 짰는데도 SVG가 화면에 아예 보이지 않는다면, 서버 설정이 제대로 되어 있지 않기 때문일 수 있습니다. 이 문제가 의심된다면 이 문서가 해결의 실마리를 제공해 줄 것입니다.
텍스트 편집기에서 SVG 파일을 열고 코드를 복사한 다음, 여러분의 HTML 문서 안에 그대로 붙여넣기 할 수도 있습니다. 이를 종종 인라인 SVG(SVG inline) 또는 인라이닝 SVG(inlining SVG)라고 부릅니다. 이때 SVG 코드 조각이 반드시 <svg> 시작 태그로 시작하고 </svg> 종료 태그로 끝나도록 해야 합니다. 다음은 문서에 코드를 붙여넣은 아주 간단한 예시입니다.
<svg width="300" height="200">
<rect width="100%" height="100%" fill="green" />
</svg>
class나 id를 부여하고 CSS로 스타일을 입힐 수 있습니다. 스타일은 SVG 내부나 HTML 문서의 외부 CSS 어디에 작성해도 다 적용됩니다. 사실, 어떠한 SVG 프레젠테이션 속성(presentation attribute)이든 CSS 속성처럼 사용할 수 있습니다.:focus 등)과 CSS 애니메이션을 SVG 이미지에 적용할 수 있는 유일한 방법입니다 (일반 외부 스타일시트에서도 가능).<a> 태그로 감싸서 하이퍼링크로 만들 수도 있습니다.💡 강사의 팁: > 실무에서, 특히 여러분들이 많이 공부하시는 React나 Next.js 환경에서는 이 인라인 방식을 아주 적극적으로 활용합니다. SVG 코드를 복사해서 하나의 'React 컴포넌트'로 만들어 두고 재사용하는 거죠. 이렇게 하면 JavaScript 구문으로 SVG의 색상이나 크기를 동적으로 바꾸기 아주 편해집니다!
<foreignObject> 요소를 사용해 대체재(fallback)를 넣을 순 있지만, 정작 SVG를 지원하는 브라우저도 대체용 이미지를 불필요하게 다운로드하게 됩니다. 이제는 잘 쓰지도 않는 구형 브라우저를 지원하자고 이런 추가적인 오버헤드를 감수할 가치가 있는지 신중히 따져보아야 합니다.iframe으로 SVG 포함하기 (How to embed an SVG with an iframe)SVG 이미지는 웹 페이지를 여는 것처럼 브라우저에서 직접 열어볼 수 있습니다. 따라서 <object>에서 <iframe>까지 — 일반적인 임베딩 기술 문서에서 배웠던 것처럼 <iframe>을 이용해 SVG 문서를 임베드할 수 있습니다.
복습 차원에서 코드를 살펴봅시다.
<iframe src="triangle.svg" width="500" height="500" sandbox></iframe>
하지만 이 방식은 절대로 추천하는 방식이 아닙니다.
<iframe> 요소는 시작 태그와 종료 태그 사이에 대체 콘텐츠(fallback)를 넣을 수 있지만, 이것은 브라우저가 <iframe> 자체를 아예 지원하지 않을 때만 화면에 표시됩니다. 정작 SVG 이미지 로딩에 실패했을 때는 이 대체 콘텐츠가 나타나지 않습니다.이번 섹션에서는 여러분이 직접 SVG를 만져보며 놀아보는 시간을 가져보려고 합니다. 공식 페이지의 Play 버튼을 눌러 MDN Playground에서 다음 예제를 열고 마음껏 코드를 편집해 보세요!
SVG 요소 레퍼런스(SVG Element Reference)에 방문해서 SVG에 내장된 수많은 유용한 요소들을 확인해 보세요. 타원 같은 다른 도형을 그려볼 수도 있고, 패턴(patterns)이나 필터 효과(filter effects)를 실험해 볼 수도 있습니다.
이 부분은 여러분의 탐구력을 발휘해서 새로운 것을 시도하고 재밌게 즐겨보는 단계입니다.
만약 코드를 수정하다가 꼬여서 잘 작동하지 않는다면 언제든지 Playground의 Reset 버튼을 눌러 초기화할 수 있으니 겁먹지 마세요!
<svg width="100%" height="100%">
<rect width="100%" height="100%" fill="red" />
<circle cx="100%" cy="100%" r="150" fill="blue" stroke="black" />
<polygon points="120,0 240,225 0,225" fill="green" />
<text
x="50"
y="100"
font-family="Verdana"
font-size="55"
fill="white"
stroke="black"
stroke-width="2">
Hello!
</text>
</svg>