개발을 할 때 (아마 백엔드 개발자는 볼 일이 없을 것이다) SVG파일을 디자이너한테 받게 되거나, 아니면 Figma에서 직접 파일을 추출해서 사용하는 경우가 있다. 보통은 SVG파일을 사용하지만, 특별한 인터렉션이 필요할 때는 직접 하드코딩해서 사용하기도 하는데 그때마다 이 코드들이 무슨 의미일까 생각은 했지만 나중에 알아보자하고 넘어갔었다. 이번 기회에 얕게라도 알아보려고 한다!
SVG는 그래픽을 그리는데 사용한다. XML을 그저 HTML에서 지원하는 하나의 태그라고 생각했지만, SVG는 탄생했을 때의 목적이 웹뿐만 아니라 모든 컴퓨터 시스템에서 벡터 그래픽을 표현하는 독립적인 문서를 만드는 것이었다. 따라서 SVG는 HTML이 아니라 XML이라는 독자적인 마크업 언어에 속한다.
서치하면서 알게 된 TMI지만 Adobe가 XML을 사용하기 위해 SVG를 주도하였다고 하네요
<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만의 문법이 존재하고, 준수해야합니다.
위에서 봤던 예제를 코드와 이미지를 통해 간단하게 알아보겠습니다. 아래 코드는 모니터 아이콘을 만드는 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> 태그 안에 작성해야합니다.

💡 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" />
이 원리로 위의 코드를 해석해보면 다음과 같습니다.
❗ 주의: 컴퓨터 그래픽, 웹 좌표계에서는 Y축이 아래로 갈수록 커집니다. 우리가 수학 시간에 배운 좌표계와 달리 '우측 아래' 방향으로 갈수록 X, Y 값이 둘 다 커진다고 생각하시면 됩니다!
무조건 SVG를 사용하는 것은 좋지 않습니다. 이 글의 마지막으로 2가지 상황을 예시로 어느 상황에 SVG를 선택하는 것이 좋을지 알아보도록 하겠습니다.
HTML 태그 내부에 인라인으로 SVG를 작성하는 것과 파일을 불러와서 사용하는 것은 생각보다 큰 차이가 있습니다.
이 둘은 전부 웹에서 그래픽을 모니터에 그리는 역할을 하지만 근본적인 원리가 다릅니다.
<rect>, <circle>, <path> 등이 엄연한 HTML/XML 태그(DOM 객체)로 존재합니다. 따라서 노드 하나하나에 onClick 이벤트를 걸거나 CSS를 줄 수 있습니다.<canvas>)를 깔아두고, JavaScript라는 붓으로 픽셀(점)을 실시간으로 칠하고 지우는 방식입니다.<canvas> 태그 딱 한 줄만 존재합니다. 화면 안의 그림들은 형태가 없는 유령이라 개별적으로 onClick 이벤트를 걸거나 CSS를 줄 수 없습니다. (마우스 좌표를 직접 수학적으로 계산해야 함)✅ 하나하나 정밀한 조작이 필요하거나 사이즈 깨짐이 없어야한다면 SVG, 많은 양의 데이터를 처리하거나 화려한 효과처럼 성능이 최우선되야 한다면 Canvas가 좋은 선택입니다.
참고:
https://developer.mozilla.org/ko/docs/Web/SVG/Tutorials/SVG_from_scratch/Introduction
https://caniuse.com/svg