Including vector graphics in HTML

김동현·2026년 3월 2일

mdn 학습 번역 - HTML

목록 보기
16/31

HTML에 벡터 그래픽 포함하기 (Including vector graphics in HTML)

벡터 그래픽이란 무엇일까요? (What are vector graphics?)

웹 개발을 하다 보면 크게 래스터 이미지(Raster images)벡터 이미지(Vector images), 이 두 가지 유형의 이미지를 다루게 됩니다.

  • 래스터 이미지는 픽셀들의 격자(grid)로 정의됩니다. 래스터 이미지 파일 안에는 각 픽셀이 어디에 위치해야 하고, 정확히 어떤 색상이어야 하는지에 대한 정보가 빼곡히 담겨 있죠. 우리가 웹에서 자주 보는 비트맵(.bmp), PNG(.png), JPEG(.jpg), GIF(.gif) 같은 포맷들이 바로 래스터 이미지입니다.
  • 벡터 이미지는 수학적 알고리즘을 사용해 정의됩니다. 벡터 이미지 파일은 컴퓨터가 화면에 이미지를 렌더링할 때 어떤 모습이어야 하는지 계산할 수 있도록, 모양(shape)과 경로(path)에 대한 정의를 담고 있습니다. SVG 포맷을 사용하면 웹에서 활용할 수 있는 강력한 벡터 그래픽을 만들 수 있답니다.

💡 강사의 팁: > 면접에서 종종 "래스터 이미지와 벡터 이미지의 차이가 무엇인가요?"라는 질문이 나옵니다. 이때 핵심 키워드는 '픽셀(해상도 의존적)''수학적 계산(해상도 독립적)'입니다. 완벽하게 대답하실 수 있겠죠?

이 둘의 차이를 좀 더 쉽게 이해하기 위해 예시를 하나 살펴볼까요? 저희 GitHub 저장소에 있는 vector-versus-raster.html 라이브 예제를 확인해 보세요. 검은색 그림자가 있는 빨간색 별 이미지 두 개가 나란히 있는데, 겉보기엔 똑같아 보입니다. 하지만 왼쪽은 PNG(래스터) 파일이고, 오른쪽은 SVG(벡터) 이미지라는 차이가 있어요.

화면을 줌인(확대)해 보면 그 차이가 확연히 드러납니다. PNG 이미지는 각 픽셀의 위치와 색상 정보만 가지고 있기 때문에 확대를 하면 이미지가 깨져 보입니다(픽셀화 현상). 화면이 커지면서 하나의 픽셀이 화면의 여러 픽셀을 채우도록 크기가 커지기 때문에 이미지가 블록처럼 각져 보이는 거죠. 반면에, 벡터 이미지는 아무리 크기를 키워도 여전히 깔끔하고 선명하게 보입니다. 크기가 변하더라도 알고리즘이 이미지의 형태를 다시 계산해서 크기에 맞게 값을 조정해 주기 때문입니다.

Two star images

Two star images zoomed in, one crisp and the other blurry

📝 참고 (Note):
위에 보여드린 두 장의 이미지는 사실 모두 PNG 파일로 캡처된 것입니다. 왼쪽 별은 래스터 이미지를 렌더링한 모습이고, 오른쪽 별은 벡터 이미지를 렌더링한 모습을 보여주기 위해 캡처한 것이죠. 진짜 동작을 보시려면 꼭 vector-versus-raster.html 데모 페이지에 들어가서 직접 화면을 확대해 보세요!

뿐만 아니라, 벡터 이미지 파일은 래스터 이미지 파일보다 용량이 훨씬 가볍습니다. 이미지 안의 수많은 픽셀 정보를 하나하나 다 저장할 필요 없이, 몇 가지 알고리즘만 가지고 있으면 되기 때문이죠.


SVG란 무엇인가요? (What is SVG?)

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는 몇 가지 추가적인 장점이 있습니다.

  • 벡터 이미지 안의 텍스트는 접근성을 유지합니다. 스크린 리더기가 읽을 수 있고 검색 엔진도 텍스트를 인식할 수 있어서 SEO(검색 엔진 최적화)에도 도움이 됩니다.
  • SVG는 스타일링과 스크립팅을 적용하기 아주 좋습니다. 이미지의 각 구성 요소가 HTML 태그와 같은 '요소(element)'이기 때문에, CSS로 스타일을 입히거나 JavaScript로 제어할 수 있습니다.

그렇다면 왜 사람들은 여전히 SVG 대신 래스터 그래픽을 사용할까요? 당연히 SVG에도 단점이 존재하기 때문입니다.

  • SVG는 금방 복잡해질 수 있고, 이는 파일 크기가 커질 수 있음을 의미합니다. 또한 구조가 복잡한 SVG는 브라우저가 화면에 그릴 때(렌더링할 때) 상당한 처리 시간을 요구하기도 합니다.
  • 만들고자 하는 이미지의 종류에 따라서는 래스터 이미지보다 SVG를 제작하는 것이 더 어려울 수 있습니다.

위에서 설명한 이유들 때문에, 사진처럼 정밀하고 복잡한 이미지를 표현할 때는 SVG보다 래스터 그래픽(JPEG, PNG 등)이 훨씬 낫다고 할 수 있습니다.

💡 강사의 팁: > 잉크스케이프나 일러스트레이터 같은 에디터에서 내보낸(export) SVG 파일 안에는 불필요한 코드가 꽤 많이 포함되어 있습니다. 그래서 웹에 실제로 올리기 전에는 SVGO와 같은 SVG 최적화 도구를 사용해서 파일 용량을 한 번 줄여주는 것이 좋습니다.


웹 페이지에 SVG 추가하기 (Adding SVG to your pages)

이 섹션에서는 여러분의 웹 페이지에 SVG 벡터 그래픽을 추가할 수 있는 여러 가지 방법들을 살펴보겠습니다.

가장 빠른 방법: img 태그 사용하기 (The quick way: img element)

<img> 요소를 통해 SVG를 포함시키려면, 일반 이미지를 넣을 때처럼 src 속성에 SVG 파일의 경로를 지정해 주면 됩니다. (다만, SVG 자체에 종횡비(aspect ratio) 정보가 없다면 heightwidth 속성, 또는 둘 다 지정해 주어야 합니다.) 아직 읽어보지 않으셨다면 HTML images 문서를 먼저 읽어보시는 것을 권장합니다.

<img
  src="equilateral.svg"
  alt="triangle with all three sides equal"
  height="87"
  width="100" />

장점 (Pros)

  • 빠르고 친숙한 이미지 삽입 문법을 사용할 수 있으며, alt 속성을 이용해 텍스트 대체재를 쉽게 제공할 수 있습니다.
  • <img> 태그를 <a> 태그로 감싸면 이미지를 아주 쉽게 하이퍼링크로 만들 수 있습니다.
  • SVG 파일이 브라우저에 캐시(cache)될 수 있습니다. 즉, 나중에 동일한 이미지를 사용하는 다른 페이지에 접속할 때 로딩 속도가 훨씬 빨라집니다.

단점 (Cons)

  • JavaScript를 사용해서 이미지를 조작할 수 없습니다.
  • CSS를 이용해 SVG 내부 콘텐츠의 스타일을 제어하고 싶다면, SVG 파일 안에 인라인 CSS 스타일 코드를 직접 작성해야 합니다. (외부 CSS 파일에서 SVG 파일을 선택해 스타일을 주려고 해도 적용되지 않습니다.)
  • :focus와 같은 CSS 가상 클래스(pseudoclasses)를 사용해 이미지 스타일을 변경할 수 없습니다.

문제 해결 및 크로스 브라우저 지원 (Troubleshooting and cross-browser support)

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가 화면에 아예 보이지 않는다면, 서버 설정이 제대로 되어 있지 않기 때문일 수 있습니다. 이 문제가 의심된다면 이 문서가 해결의 실마리를 제공해 줄 것입니다.

HTML 안에 직접 SVG 코드 포함하기 (How to include SVG code inside your HTML)

텍스트 편집기에서 SVG 파일을 열고 코드를 복사한 다음, 여러분의 HTML 문서 안에 그대로 붙여넣기 할 수도 있습니다. 이를 종종 인라인 SVG(SVG inline) 또는 인라이닝 SVG(inlining SVG)라고 부릅니다. 이때 SVG 코드 조각이 반드시 <svg> 시작 태그로 시작하고 </svg> 종료 태그로 끝나도록 해야 합니다. 다음은 문서에 코드를 붙여넣은 아주 간단한 예시입니다.

<svg width="300" height="200">
  <rect width="100%" height="100%" fill="green" />
</svg>

장점 (Pros)

  • SVG를 인라인으로 삽입하면 별도의 HTTP 네트워크 요청을 한 번 아낄 수 있어서 페이지 로딩 시간을 조금 단축시킬 수 있습니다.
  • SVG 요소에 classid를 부여하고 CSS로 스타일을 입힐 수 있습니다. 스타일은 SVG 내부나 HTML 문서의 외부 CSS 어디에 작성해도 다 적용됩니다. 사실, 어떠한 SVG 프레젠테이션 속성(presentation attribute)이든 CSS 속성처럼 사용할 수 있습니다.
  • 인라인 SVG 방식은 CSS 인터랙션(:focus 등)과 CSS 애니메이션을 SVG 이미지에 적용할 수 있는 유일한 방법입니다 (일반 외부 스타일시트에서도 가능).
  • SVG 마크업을 <a> 태그로 감싸서 하이퍼링크로 만들 수도 있습니다.

💡 강사의 팁: > 실무에서, 특히 여러분들이 많이 공부하시는 React나 Next.js 환경에서는 이 인라인 방식을 아주 적극적으로 활용합니다. SVG 코드를 복사해서 하나의 'React 컴포넌트'로 만들어 두고 재사용하는 거죠. 이렇게 하면 JavaScript 구문으로 SVG의 색상이나 크기를 동적으로 바꾸기 아주 편해집니다!

단점 (Cons)

  • 이 방식은 해당 SVG가 페이지 내에서 딱 한 곳에만 쓰일 때 적합합니다. 똑같은 긴 SVG 코드를 여러 곳에 복사해서 붙여넣으면 나중에 유지보수하기가 너무 힘들어집니다.
  • HTML 문서 안에 SVG 코드가 너무 많아지면 HTML 파일의 용량 자체가 커집니다.
  • 브라우저가 인라인 SVG 코드를 일반 이미지 자산(asset)처럼 독립적으로 캐싱할 수 없습니다. 따라서 여러 페이지에서 동일한 이미지를 쓰더라도 첫 방문 이후의 로딩 속도 이점을 얻지 못합니다.
  • <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>

하지만 이 방식은 절대로 추천하는 방식이 아닙니다.

단점 (Cons)

  • <iframe> 요소는 시작 태그와 종료 태그 사이에 대체 콘텐츠(fallback)를 넣을 수 있지만, 이것은 브라우저가 <iframe> 자체를 아예 지원하지 않을 때만 화면에 표시됩니다. 정작 SVG 이미지 로딩에 실패했을 때는 이 대체 콘텐츠가 나타나지 않습니다.
  • 게다가 SVG 파일과 현재 웹 페이지의 출처(origin)가 다를 경우, 메인 웹 페이지에 있는 JavaScript로 SVG를 조작하는 것이 보안 정책상 차단됩니다.

SVG로 놀아보기 (Playing with 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>
profile
프론트에_가까운_풀스택_개발자

0개의 댓글