1. SVG란?

SVG는, 확장 가능한 벡터 그래픽(Scalable Vector Graphics)을 말합니다.
2차원 그래픽을 표현하기 위해 만들어진 XML파일 형식의 마크업 언어인데요,
텍스트 편집기에서 CSS나 JS로 수정이 가능하다는 점이 가장 큰 장점이라 할 수 있습니다.

또, 확장이 가능하다는 점에서 확대해도 품질이 떨어지지 않습니다.
레티나나 모바일에 대응하기 위한 추가 작업도 필요 없고, 시각 장애가 있는 사용자들이 웹을 확대하더라도 품질 저하의 문제가 없죠!

단, 미지원 브라우저가 있습니다. IE 8이라던가 IE 8이라던가 뭐 IE 같은 거요

( IE8 이전 버전을 제외한 대부분의 브라우저에서 지원됩니다. )

 

 

2. SVG의 장점

  • 반응형 대응, 사이즈 변화에 지장 없음
  • 브라우저 호환성
  • SVG 속성 사용

 

 

3. 참고사이트

 

 


 

4. SVG 사용하기

 

SVG는 도형과 선으로 이루어져 있고, 직접 path의 값을 입력해 뭔가를 그려낼 수.....도 있기는 합니다. 

하지만 그걸 배우고 있다가는 SVG를 써먹기도 전에 나가 떨어질 거 같아 우선은 생략!하고,

어도비 일러 등에서 그려낸 SVG를 웹페이지에 어떻게 삽입하는지 살펴보겠습니다.

 

자, 여기 SVG가 하나 있습니다. 이 이미지를 일러스트레이터로 열었을 때, 아트보드의 크기는 512*512였습니다.

 

 

 

 

1) img 태그

<img src="nana.svg" />

 

SVG는 일반적인 이미지처럼 img 태그를 통해 삽입할 수 있습니다.

 

 

하지만 이렇게 해놓고 웹페이지를 열어보면, SVG이미지가 문서 전체 크기만큼 차지하고 있는 걸 볼 수 있습니다.

그래서 img 태그에 width, height 값을 지정하거나 css로 width 값을 지정하여 크기 조절이 가능합니다.

 

이 방식은 IE 8, 안드로이드 2.3 이상에서 지원됩니다.

만약 이런 구닥다리 버전까지 지원해야 한다면? Modernizr를 통해 분기점을 만들고 png로 대체하는 등의 방법이 있겠죠.

근데 그럴 거면 그냥 SVG 안 쓰는 게 나을 거 같은데요오......?

 

 

2) background-image

.nana {
  width: 300px;
  height: 120px;
  outline: 2px solid red;
  background-image: url("./potion.svg");
}

 

이것도 일반적인 이미지처럼 background-image 속성을 이용하는 방법입니다.

width: 300px; height: 120px; 을 준 상태에서 브라우저를 열어봤더니...

 

 

높이(120px)에 맞춰 이미지 크기가 줄어든 걸 확인할 수 있습니다.

반복되는 걸 피하려면 no-repeat를 주거나, background-size를 지정하면 되겠네요.

 

마찬가지로 IE 8과 안드로이드 2.3 이하 버전은 지원하지 않습니다.

다만, background-image로 넣는 경우엔 Modernizr를 활용하기가 좀 더 수월합니다.

.no-svg 같은 클래스를 html에다 붙이고 분기시키면 되거든요.

.nana {
  background: url(nana.svg) no-repeat top left;
  background-size: contain;
}
.no-svg .nana {
  background-image: url(nana.svg);
}

 

아니면 이렇게 하는 방법도 있습니다.

SVG를 지원하는 브라우저가 이전 선언을 무시하게 만드는 거죠.

.nanakkli {
  background: url(nana.png);
  background-image: url(nana.svg);
}

그런데... 이 두 가지 방법(img 태그와 bgimage)에는 문제가 있습니다.

CSS로 SVG 내부를 제어할 수가 없거든요 ;ㅁ;

 

그래서 SVG 내부 코드를 제어할 필요가 없지만, 이미지는 유연하게 반응형 처리하고 싶다! 할 때 쓰면 되겠습니다.

 

 

 

3) 인라인

 

아니면 인라인도 있습니다. HTML 상에 코드를 때려박는 거에요.

장점은 이미지 로드가 필요 없죠. 추가 HTTP 요청을 할 필요가 없기 때문에 속도가 빠릅니다.

단점은 HTML이 더러워(...)지고 캐싱이 불가능합니다. 그래서 로드될 때마다 읽어야 해요.

 

고대 브라우저 지원은 이렇게 하세요.

fallback이라는 요소를 마크업 해두고, SVG 미지원 브라우저일 때는 png 이미지가 보이게끔 처리합니다.

<svg> ... </svg>
<div class="fallback"></div>
.fallback { 
  display: none;
}
.no-svg .fallback { 
  background-image: url(nana.png); 
}

 

 

4) object

 

또는 object라는 방법도 있어요!

type이 src가 아닌 data라는 데 주의합시다.

 

<object type="image/svg+xml" data="./potion.svg" class="nana"></object>

 

이 방법은 캐싱이 되지만, 외부 CSS기능을 쓸 수 없습니다(뜨든).

object에 대한 스타일링은 가능하지만, svg 내부 코드는 조작할 수가 없어요.

 

SVG 파일 자체에 <style>을 박아야만 하죠.

<svg>
  <style>
    .potion1 {
      fill: #ffeb3b;
    }
  </style>
  
  <path class="potion1" d="....."/>
</svg>

 

외부 스타일을 꼭 쓰고 싶다면 이렇게 연결하는 방법도 있습니다.

우선 HTML에서 외부 스타일시트를 연결하고...

<link rel="stylesheet" href="style.css"/>

<object type="image/svg+xml" data="./potion.svg" class="object"></object>

 

SVG 파일을 연 다음, 최상단에 아래 코드를 삽입합니다.

<?xml-stylesheet type="text/css" href="style.css"?>
 
<svg>
  <path class="potion1" d="....."/>
  <path class="potion2" d="....."/>
</svg>

 

그런 다음 style.css 내부에서 스타일링해줍니다.

.object {
  width: 300px;
  height: 300px;
}
.svg:hover .potion1 {
  fill: #eddd50;
}
.svg:hover .potion2 {
  fill: #ccbb23;
}

 

 

이 방식은 캐싱이 되고, HTML이 깔끔해지며, SVG 코드 조작이 가능하다는 장점이 있지만

스타일시트를 한 번 더 연결해야하고, 링크가 안 걸린다는 단점이 있습니다.

object를 a 태그로 감싸도 링크가 안 걸리거든요.

 

그럴 땐 svg 코드 내에 a를 넣어주면 됩니다.

<svg>
 <a xlink:href="https://nykim.work" target="_blank">
   <rect x="10" y="10" height="100" width="100"
         style="stroke:#009900; fill: gold"/>
 </a>
</svg>

아니면 이런 방식도 있겠죠.

a태그를 absolute 시키는 방법입니다.

<div class="parent">
  <a href="https://nykim.work">링크 영역</a>
  <object type="image/svg+xml" data="./potion.svg" class="object"></object>
</div>
.parent {
  position: relative;
  outline: 2px solid red;
  width: 300px;
  height: 300px;
}
.parent a {
  display: block;
  position: absolute;
  width: 100%;
  height: 100%;
  color: #fff;
  background: rgba(0, 0, 0, 0.411);
}

 

 

마지막으로 폴백처리는 이렇게 해주면 됩니다.

(만약 IE 8 같은 유물을 지원해야 하면 말이죠!)

.no-svg .nana {
  width: 152px;
  height: 152px;
  background-image: url(nana.png);
}

 

정리하자면 이정도가 되겠네요!

 

나는 SVG가 필요하지만 이미지에 별다른 조작을 가하지 않을 것이다 👉<img/> 또는 background-image

나는 SVG가 필요하고 이미지에 조작을 가할 것이다 👉인라인 또는 <object>

 

 

 

 


 5. CSS로 SVG 애니메이션 조작하기

 

이론적인 것도 매우 중요하지만,

우리가 하고 싶은 건 막 푸슝하고 피융하고 슈슈슉하고 움직이는 그런 거잖아요?!

그러니 지나가는 아무 SVG나 붙잡고 이것저것 조작해보자구요!

 

저는 여기서 다운받은, 아까 그 포션 SVG를 사용하겠습니다.

포션 병 근처의 하트가 움직이는 모션을 주려고요 ;)

 

막 다운받은 SVG 코드는 좀 더럽the love기 때문에 SVGO 등을 통해 압축해 줍니다.

웹이라면 SVGOMG를 통해서 손쉽게 압축할 수도 있습니다.

	
<?xml-stylesheet type="text/css" href="style.css"?>
<svg xmlns="http://www.w3.org/2000/svg" class="svg" viewBox="0 0 512.001 512.001">
	<path class="heart1" d="M145.374 31.943c-52.434-58.261-99.042 0-75.739 46.608s75.739 64.086 75.739 64.086 52.434-17.478 75.739-64.086-23.305-104.868-75.739-46.608z" fill="#ffb1bb"/>
	<path class="heart2" d="M95.189 275.054c-28.686-31.873-54.183 0-41.434 25.498s41.434 35.06 41.434 35.06 28.686-9.561 41.434-35.06c12.749-25.498-12.748-57.371-41.434-25.498z" fill="#ffd8dd"/>
	<path class="heart3" d="M416.811 146.405c-28.686-31.873-54.183 0-41.434 25.498s41.434 35.06 41.434 35.06 28.686-9.562 41.434-35.06c12.749-25.498-12.749-57.371-41.434-25.498z" fill="#fe6a89"/>
	<g class="flask-top" fill="#efecf1">
		<path d="M195.114 158.72h128.649v32.162H195.114z"/>
		<path d="M426.851 466.796l-127.21-187.469v-88.446h-80.405v88.446L92.024 466.796c-10.868 16.017.605 37.666 19.96 37.666h294.908c19.355 0 30.828-21.65 19.959-37.666z"/>
	</g>
	<path d="M243.357 287.368v-56.284c0-8.882 7.199-16.081 16.081-16.081h40.203v-24.122h-80.405v88.446l-48.877 72.03h29.385l43.613-63.989z" fill="#e0dae3"/>
	<path d="M170.358 351.356l-78.334 115.44 78.334-115.44z" fill="#fe5578"/>
	<path class="potion1" d="M348.518 351.356h-178.16l-78.334 115.44c-10.868 16.017.605 37.666 19.96 37.666h294.908c19.356 0 30.828-21.65 19.96-37.666l-78.334-115.44z" fill="#fe5578"/>
	<path class="potion2" d="M137.501 442.674l62.241-91.317h-29.385L92.024 466.796c-10.868 16.017.605 37.666 19.96 37.666h294.908c14.175 0 24.111-11.615 24.15-24.122h-273.58c-19.356 0-30.828-21.65-19.961-37.666z" fill="#fe3f67"/>
	<path fill="#fe5578" d="M348.518 351.356l78.333 115.44z"/>
	<path class="flask-heart" d="M259.438 403.702c-28.686-31.873-54.183 0-41.434 25.497 12.749 25.498 41.434 35.06 41.434 35.06s28.686-9.561 41.434-35.06c12.749-25.497-12.749-57.37-41.434-25.497z" fill="#efecf1"/>
</svg>

그리고 우리가 흔히 하던 것처럼 CSS 애니메이션을 작성합니다.

@keyframes fadeOut {
  0% {
    opacity: 1;
    transform: translate3d(0px, 35px, 0);
  }
  30% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    transform: translate3d(0px, 0px, 0);
  }
}
 
.heart1 {
  animation: fadeOut 1s infinite;
}
.heart2 {
  animation: fadeOut 1.5s infinite;
}
.heart3 {
  animation: fadeOut 1.25s infinite;
}

 

네, 뭐. 푸슝하고 피융하는 그런 건 아니지만 아무튼 이미지를 조작할 수 있게 됐습니다! 〔´∇`〕

 

 



6. JS로 SVG 애니메이션 조작하기

 

CSS로 조작이 가능하다면, JS로도 물론 가능하겠죠!

스크롤매직 라이브러리에서도 잘 써먹었던 GSAP을 가져다 써보겠습니다.

 

한 가지 주의할 점은, 라인 애니메이션을 그리기 위해서는 shape가 아니라 open path여야 한다는 점입니다.

 

(좌) Shape
(우) Open path

 

 

 

See the Pen eYOjPYb by NY KIM (@nykim_) on CodePen.

 

 

 

 

 

 

 

 

출처 : https://nykim.work/35

출처 : https://velog.io/@zansol/SVG-%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C

 

+ Recent posts