SVG에 대하여 알아보자

John Han·2026년 6월 9일
post-thumbnail

개발을 할 때 (아마 백엔드 개발자는 볼 일이 없을 것이다) SVG파일을 디자이너한테 받게 되거나, 아니면 Figma에서 직접 파일을 추출해서 사용하는 경우가 있다. 보통은 SVG파일을 사용하지만, 특별한 인터렉션이 필요할 때는 직접 하드코딩해서 사용하기도 하는데 그때마다 이 코드들이 무슨 의미일까 생각은 했지만 나중에 알아보자하고 넘어갔었다. 이번 기회에 얕게라도 알아보려고 한다!

SVG란

SVG는 그래픽을 그리는데 사용한다. XML을 그저 HTML에서 지원하는 하나의 태그라고 생각했지만, SVG는 탄생했을 때의 목적이 웹뿐만 아니라 모든 컴퓨터 시스템에서 벡터 그래픽을 표현하는 독립적인 문서를 만드는 것이었다. 따라서 SVG는 HTML이 아니라 XML이라는 독자적인 마크업 언어에 속한다.

서치하면서 알게 된 TMI지만 Adobe가 XML을 사용하기 위해 SVG를 주도하였다고 하네요

HTML 태그 사이에 작성되는 <svg> 태그의 정체는 무엇인가?

평소 개발할 때 HTML 파일이나 React 컴포넌트 내부에 별도의 선언 없이 <svg>,<path>,<g> 등...의 SVG 태그들을 사용할 수가 있습니다. 아래 코드는 제가 프로젝트를 진행하며 직접 작성하였던 코드입니다.

export default function MobileBlockOverlay() {
  const [visible, setVisible] = useState(false);
  const [index, setIndex] = useState(0);

  useEffect(() => {
    if (isElectron()) return;
    setVisible(isMobileOrTablet());
  }, []);

  // 생략 ...

  return (
    <div
      style={{
        position: "fixed",
		// 생략 ...
        padding: "2rem",
      }}
    >
      {/* SVG 아이콘 */}
      <div
        style={{
          marginBottom: "1.5rem",
          animation: "mbo-float 3s ease-in-out infinite",
        }}
      >
        <svg
          width="64"
          height="64"
          viewBox="0 0 24 24"
          fill="none"
          stroke="rgba(255,255,255,0.9)"
          strokeWidth="1.5"
          strokeLinecap="round"
          strokeLinejoin="round"
        >
          <rect x="2" y="3" width="20" height="14" rx="2" />
          <path d="M8 21h8M12 17v4" />
        </svg>
      </div>


      <div
        key={index}
        style={{
          textAlign: "center",
          animation: "mbo-fadein 0.5s ease-out",
        }}
      >
        {/* 생략 */}
      </div>

      <style>{`
        @keyframes mbo-float {
          0%, 100% { transform: translateY(0px); }
          50% { transform: translateY(-8px); }
        }
        @keyframes mbo-fadein {
          from { opacity: 0; transform: translateY(6px); }
          to   { opacity: 1; transform: translateY(0px); }
        }
      `}</style>
    </div>
  );
}


2014년에 HTML5 스펙이 도입되면서 웹 브라우저 내부에서 인라인 SVG 기능이 탑재되었기 때문에 처리가 가능하게 되었습니다. React나 HTML이나 브라우저가 이들을 최종적으로 다루는 것은 DOM 엘리먼트입니다. 브라우저 내부에서는 이들을 똑같은 태그로 보지 않고 내부적으로 클래스를 나누어 관리합니다. 예를 들자면 다음과 같습니다.

  • <div>: HTMLDivElement 객체로 생성 (HTML)
  • <rect>: SVGRectElement 객체로 생성 (XML/SVG)

따라서 SVG는 XML이라는 문법 규칙 체계가 존재합니다. 따라서 대소문자를 엄격하게 구분, 모든 태그는 열고 닫는다 등 XML만의 문법이 존재하고, 준수해야합니다.

SVG 사용하기

위에서 봤던 예제를 코드와 이미지를 통해 간단하게 알아보겠습니다. 아래 코드는 모니터 아이콘을 만드는 XML 태그입니다.

        <svg
          width="64"
          height="64"
          viewBox="0 0 24 24"
          fill="none"
          stroke="rgba(255,255,255,0.9)"
          strokeWidth="1.5"
          strokeLinecap="round"
          strokeLinejoin="round"
        >
          <rect x="2" y="3" width="20" height="14" rx="2" />
          <path d="M8 21h8M12 17v4" />
        </svg>

앞서 말했지만 SVG는 위의 예제 코드 같이 HTML에 인라인으로 작성을 하거나, SVG확장자 파일로서 사용할 수 있습니다. 이때 SVG 파일을 코드 에디터로 열어보시면 xmlns를 확인할 수 있습니다.

<svg width="73" height="73" viewBox="0 0 73 73" fill="none" xmlns="http://www.w3.org/2000/svg">

이것은 해당 파일이 단순한 텍스트가 아니라 SVG 그래픽 파일이라고 명시하는 중요한 속성입니다. .svg 파일은 HTML이 아닌 독립적인 XML 문서이기 때문입니다. 즉 네임스페이스 식별자라는 일종의 고유 이름표입니다.

XML은 SVG 외에도 다양하게 사용됩니다. 웹 도메인은 고유하기 때문에 도메인 주소를 통해 컴퓨터에게 이 XML문서는 그래픽 전용 태그들임을 확실하게 가리켜주는 고유 ID 역할을 수행하게 됩니다.

💡 인라인에서는 필요 없지만, SVG 파일에서는 반드시 xmlns="http://www.w3.org/2000/svg"를 작성해야합니다!

그럼 다시 돌아와서 어떻게 도형을 그릴 수 있는 것인가 간단하게 살펴보겠습니다. 먼저 <svg>태그에 대해서 알아보겠습니다. 이 태그의 열고, 닫음은 여기서부터는 HTML이 아니라 XML을 사용한 그래픽 태그임을 명시하는 중요한 택입니다. 따라서<rect>,<g>,<path>와 같은 모든 XML 태그들은 반드시 <svg> 태그 안에 작성해야합니다.

  • width, height: 속성은 실제 화면에서 그려질, 해당 svg가 차지할 공간(가로, 세로 길이입니다. 단위는 px)
  • viewBox: 내부에서 사용할 가상의 모눈종이 규격, 좌표입니다. "0 0 24 24"라면 시작점(0, 0)과 가로 길이(24), 세로 길이(24)를 좌표 기준으로 생성된 사각형 공간입니다.

💡 SVG는 수학 공식으로 이루어져 있어서, 이미지 파일과 다르게 사이즈를 늘리거나 줄여도 깨지지 않습니다. 따라서 viewBox 기준으로 가로가 24이며 width 기준으로는 가로 64여도 선명함을 유지할 수 있습니다. 이것을 벡터라고 부릅니다.

다음으로 <rect> 사각형을 그리는 태그입니다.

<rect x="2" y="3" width="20" height="14" rx="2" />

x와 y 속성은 사각형을 그리기 시작하는 지점입니다. 위에서 설정한 <svg>의 viewBox는 길이가 24인 정사각형입니다. 따라서 좌표 (2,3)에서 가로, 세로 길이가 각각 20과 14인 사각형을 그리면 다음과 같이 A(2,3), B(22,3), C(22,17), D(2,17)에 꼭지점이 있는 사각형이 만들어집니다. (rx는 radiusX입니다. 반대로 ry도 존재합니다)

다음으로는 <path> 펜으로 선을 그리는 태그입니다. d 속성에는 펜을 컨트롤 하는 명령어를 작성합니다.

<path d="M8 21h8M12 17v4" />
  • Mx y: Move to (x, y) viewBox라는 가상의 모눈종의에서 펜을 때고 해당 좌표로 이동합니다
  • hn: horizontal lineto (x+n,y0) 현재 위치에서 오른쪽으로 n만큼 오른쪽으로 가로 선을 그습니다.
  • vn: vertical lineto (x0, y+n) 현재 위치에서 아래로 n만큼 세로 선을 긋습니다.

이 원리로 위의 코드를 해석해보면 다음과 같습니다.

  • M8 21: 펜을 들어 (8, 21) 좌표로 간다. (받침대 바닥 왼쪽 끝)
  • h8: 그 자리에서 오른쪽으로 8칸만큼 선을 긋는다. (그럼 (16, 21)까지 선이 그려지며 바닥 지지대가 완성됩니다.)
  • M12 17: 다시 펜을 들어 모니터 화면 아래 정중앙인 (12, 17) 좌표로 간다.
  • v4: 그 자리에서 아래쪽으로 4칸만큼 수직 선을 내리긋는다. (바닥 지지대와 화면을 연결하는 기둥 완성!)

    ❗ 주의: 컴퓨터 그래픽, 웹 좌표계에서는 Y축이 아래로 갈수록 커집니다. 우리가 수학 시간에 배운 좌표계와 달리 '우측 아래' 방향으로 갈수록 X, Y 값이 둘 다 커진다고 생각하시면 됩니다!

어느 상황에 SVG를 사용하면 좋을까?

무조건 SVG를 사용하는 것은 좋지 않습니다. 이 글의 마지막으로 2가지 상황을 예시로 어느 상황에 SVG를 선택하는 것이 좋을지 알아보도록 하겠습니다.

CASE1: Inline SVG vs .svg 파일

HTML 태그 내부에 인라인으로 SVG를 작성하는 것과 파일을 불러와서 사용하는 것은 생각보다 큰 차이가 있습니다.

Inline SVG

  • 인라인 SVG 장점: 코드의 일부로서 CSS나 JavaScript로 디자인 커스텀, 에니메이션 등 다양한 조작이 가능합니다(위 코드 참고). 또한, 웹에서는 다운로드 없이 화면에 즉시 렌더링 됩니다.
  • 인라인 SVG 단점: 피그마 같은 곳에서 추출한 수백줄짜리 좌표 코드가 소스 코드를 차지하므로 코드가 지저분해집니다. 복잡한 SVG 파일이라면 그리는 시간이 다운로드 시간보다 오래 걸릴 수 있습니다.

.svg 파일

  • 파일 장점: 소스 코드가 매우 깔끔해지고, 하나의 파일로서 브라우저가 캐싱이 가능하여 웹 성능과 용량 최적화에 유리합니다.
  • 파일 단점: 독립된 파일로 CSS나 JS로 디자인 커스텀이 불가능합니다.

CASE2: SVG vs HTML5 Canvas

이 둘은 전부 웹에서 그래픽을 모니터에 그리는 역할을 하지만 근본적인 원리가 다릅니다.

SVG

  • 원리: 모눈종이 위에 수학적 좌표를 찍어 선을 긋는 벡터(Vector) 방식입니다.
  • 특징: 아무리 확대해도 컴퓨터가 수학적으로 다시 계산해서 그리기 때문에 절대 깨지지 않고 칼같이 선명합니다.
  • 정체: 내부의 <rect>, <circle>, <path> 등이 엄연한 HTML/XML 태그(DOM 객체)로 존재합니다. 따라서 노드 하나하나에 onClick 이벤트를 걸거나 CSS를 줄 수 있습니다.
  • 한계: 화면에 움직이는 물체(노드, 별, 빗방울 등)가 수천, 수만 개로 많아지면 브라우저가 그 수많은 태그를 계산하느라 컴퓨터가 엄청나게 느려집니다.

Canvas

  • 원리: 하나의 도화지 태그(<canvas>)를 깔아두고, JavaScript라는 붓으로 픽셀(점)을 실시간으로 칠하고 지우는 방식입니다.
  • 특징: 정해진 해상도(픽셀) 영역에 그림을 그리는 것이라, 화면을 강제로 확대하면 일반 사진처럼 주변이 흐려지거나 깨집니다.
  • 정체: 사각형을 백 개 그려도 HTML에는 오직 <canvas> 태그 딱 한 줄만 존재합니다. 화면 안의 그림들은 형태가 없는 유령이라 개별적으로 onClick 이벤트를 걸거나 CSS를 줄 수 없습니다. (마우스 좌표를 직접 수학적으로 계산해야 함)
  • 장점: 태그를 관리하지 않고 픽셀만 빛의 속도로 덧칠하기 때문에, 수만 개의 입자가 날아다녀도 렉 없이 엄청나게 빠릅니다.

✅ 하나하나 정밀한 조작이 필요하거나 사이즈 깨짐이 없어야한다면 SVG, 많은 양의 데이터를 처리하거나 화려한 효과처럼 성능이 최우선되야 한다면 Canvas가 좋은 선택입니다.

참고:
https://developer.mozilla.org/ko/docs/Web/SVG/Tutorials/SVG_from_scratch/Introduction
https://caniuse.com/svg

profile
Hello World!

0개의 댓글