오늘은 CSS 애니메이션을 활용해 SVG 화살표 아이콘이 위아래로 튀어 오르는 효과를 만드는 방법을 알아보겠습니다. 아울러 CSS 애니메이션 속성들을 사용해 애니메이션의 유형, 타이밍, 지속 시간을 자유롭게 조절하는 방법도 함께 배워보겠습니다.
왜 이 기술이 유용할까요?
애니메이션을 적절하게 활용하면 다음과 같은 효과를 얻을 수 있습니다.
- 사용자를 자연스럽게 안내할 수 있습니다
- 사용자가 행동을 취하도록 유도할 수 있습니다
- 사용자의 관심을 사로잡을 수 있습니다
준비물
실습을 따라 하려면 코드 편집기가 필요합니다. 로컬 개발 환경이 없다면 CodePen을 추천합니다. 별도의 설정 없이 바로 코딩을 시작할 수 있기 때문입니다.
자, 그럼 시작해 보겠습니다!
HTML: 컨테이너와 화살표 추가하기
데모 예제를 재현하려면 다음 네 가지 HTML 요소가 필요합니다.
- 화살표 아이콘을 담을 이미지(SVG) 요소
- 화살표 위에 표시될 텍스트 레이블용 span 요소
- 화살표와 텍스트 레이블을 감싸는 container-footer 요소
- 모든 요소를 감싸는 container 요소
HTML 편집기를 열고 <body></body> 요소 안에 다음 마크업을 추가하세요.
<div class="container">
<div class="container-footer">
<span class="text-label">Explore</span>
<svg
class="arrow-circle-down bounce"
viewbox="0 0 1792 1792"
xmlns="https://www.w3.org/2000/svg"
>
<path
d="M1412 897q0-27-18-45l-91-91q-18-18-45-18t-45 18l-189 189v-502q0-26-19-45t-45-19h-128q-26 0-45 19t-19 45v502l-189-189q-19-19-45-19t-45 19l-91 91q-18 18-18 45t18 45l362 362 91 91q18 18 45 18t45-18l91-91 362-362q18-18 18-45zm252-1q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"
fill="#fff"
></path>
</svg>
</div>
</div>
위에서 추가한 화살표 코드는 SVG 형식이며, Font Awesome CSS 아이콘 라이브러리를 기반으로 합니다. GitHub 저장소에서 수백 가지 Font Awesome 아이콘을 SVG 형식으로 선택해 사용할 수 있습니다.
리소스를 아껴 사용하세요!
많은 웹사이트가 실제로 사용하는 아이콘은 몇 개뿐인데도 Font Awesome 라이브러리 전체를 로드합니다. 이는 대역폭 낭비입니다. 실제로 필요한 5~10개 정도의 아이콘만 SVG 형식으로 내려받아 사용하면 상당한 리소스를 절약할 수 있습니다.
이번 예제에서는 SVG 파일을 HTML 마크업에 직접 삽입했습니다. 이 방식을 인라인 SVG(inline SVG)라고 부릅니다. 용도에 따라 SVG를 추가하는 방법은 여러 가지가 있지만, 그 내용은 별도의 튜토리얼에서 다루겠습니다.
원본 SVG 소스와 위 HTML 마크업에 있는 코드를 비교해 보면 몇 가지 변경 사항이 있습니다.
- width와 height 속성을 제거했습니다 (원본 파일 크기가 너무 큽니다)
- CSS 섹션에서 사용할 클래스
arrow-circle-down을 추가했습니다
이제 스타일을 조금 추가하고, 본격적으로 CSS 애니메이션의 재미있는 부분으로 넘어가 보겠습니다!
CSS로 컨테이너와 화살표 스타일링하기
CSS 스타일시트에 다음 규칙(클래스, 속성, 값)을 추가하세요.
* {
margin: 0;
padding: 0;
}
.container {
display: flex;
background-color: #26a1ff;
height: 100vh;
}
.container-footer {
display: flex;
flex-direction: column;
align-items: center;
margin: auto auto 1rem auto;
}
.text-label {
text-transform: uppercase;
font-family: helvetica;
font-size: 0.75rem;
letter-spacing: 0.2em;
color: #fff;
}
.arrow-circle-down {
display: block;
width: 40px;
height: 40px;
margin: 16px 0;
}
브라우저 창을 새로고침하면 다음과 같은 화면이 나타납니다.
CSS에서 일어나는 일을 살펴보겠습니다.
- 먼저 부모 div 요소인
.container클래스에 height 값을 100vh로 지정해 어떤 기기에서든 전체 뷰포트를 차지하도록 만듭니다.display: flex;속성으로 플렉스 컨테이너로 만들어 화살표와 텍스트 레이블 배치에 활용하고, 보기 좋은 연한 파란색 배경도 입혀줍니다. .arrow-circle-down클래스에는 고정된 너비와 높이 40px를 지정해 화면에서 과도한 공간을 차지하지 않도록 합니다. 눈에 띄되 방해가 되지 않는 크기입니다..text-label에는 uppercase 속성과 letter-spacing으로 세련된 스타일을 더했습니다. 원하는 대로 자유롭게 수정해도 됩니다..container-footer에는 top, right, left 방향에 margin auto를 지정했습니다. 이렇게 하면 컨테이너 푸터와 그 자식 요소(아이콘과 텍스트)가 부모 컨테이너의 하단으로 밀려나게 되는데, 우리가 원하는 위치입니다. bottom 마진에는1rem;값을 주어 화살표가 튀어 오를 때 모든 요소가 뷰포트 안에 머무르도록 합니다..container-footer클래스에는flex-direction: column;과align-items: center;같은 플렉스 속성도 적용했습니다. 이 속성들은 텍스트와 아이콘 요소를 세로로 쌓고 컨테이너 푸터의 정중앙에 정렬해 줍니다.
참고로 margin: auto auto 1rem auto 선언은 다음의 긴 버전을 축약한 것입니다.
margin-top: auto;
margin-right: auto;
margin-bottom: 1rem;
margin-left: auto;
이제 CSS 애니메이션으로 화살표를 튀게 만들어 볼 시간입니다!
CSS로 아래로 스크롤하는 화살표 애니메이션 만들기
애니메이션을 구현하는 방법은 CSS, JavaScript 또는 두 가지의 조합 등 매우 다양합니다. 이번 예제에서는 순수하게 CSS만으로 애니메이션을 만들어 보겠습니다.
SVG 화살표가 들어 있는 이미지 요소에는 이미 .bounce 클래스를 추가해 두었습니다. 아직 CSS에서 이 클래스를 정의하지 않았기 때문에 지금은 아무 효과가 없습니다.
CSS 스타일시트에 다음 코드를 추가하세요.
.bounce {
animation: bounce 2s;
}
@keyframes bounce {
0%,
25%,
50%,
75%,
100% {
transform: translateY(0);
}
40% {
transform: translateY(-20px);
}
60% {
transform: translateY(-12px);
}
}
이제 튀어 오르는 화살표가 완성되었습니다!
CSS 코드 분석
화살표가 있는 SVG 요소에는 .bounce라는 클래스가 있고, 이 클래스에는 animation 속성이 정의되어 있습니다.
animation 속성에는 bounce와 2s라는 두 가지 값이 있습니다.
bounce 값은 곧 설명할 @keyframes 애니메이션 @keyframes bounce를 실행시키는 함수입니다.
2s(2초) 값은 @keyframes 애니메이션이 실행될 총 시간입니다.
@keyframes 애니메이션의 특징:
- 총 지속 시간은 2초입니다 (animation 속성으로 설정)
- 0%, 25%, 40%, 50%, 60%, 75%, 100%까지 총 7개의 서로 다른 키프레임이 있습니다
- Y(0), Y(-20px), Y(-12px)라는 세 가지 Y 좌표 위치가 있습니다. 이 좌표들이 시간의 흐름에 따라(각 키프레임 지점에서) 화살표 요소가 위로 움직일지 아래로 움직일지를 결정합니다
첫 번째 @keyframes 블록 {..}은 0%, 25%, 50%, 75%, 100%라는 다섯 개의 키프레임 지점에서 화살표가 시작 위치인 Y(0px)에 있어야 한다는 의미입니다.
0%,
25%,
50%,
75%,
100% {
transform: translateY(0);
}
두 번째 @keyframes 블록은 40% 지점에서 화살표가 Y(-20px) 위치로 위로 이동해야 한다는 의미입니다.
40% {
transform: translateY(-20px);
}
세 번째 키프레임 블록은 60% 지점에서 화살표가 다시 위로 이동한다는 의미입니다. 이번에는 첫 번째 이동의 절반 정도인 Y(-12px)만큼만 올라갑니다.
60% {
transform: translateY(-12px);
}
주목할 점은 화살표가 위로 움직이는 두 키프레임(40%와 60%) 사이에 50% 키프레임에서 다시 Y(0)로 돌아온다는 것입니다. 바로 이 부분 때문에 화살표가 짧은 시간 동안 비교적 빠르게 두 번 위아래로 움직이는 것입니다.
세 번째 위치에서 화살표를 -12px만 이동시키기로 한 이유는 실제 공이 튀는 모습을 모방하기 위해서입니다. 공이 두 번째로 바닥에 닿으면 첫 번째보다 훨씬 낮게 튀어 오르죠. 물론 공이 얼마나, 얼마나 높이 튀는지는 무게, 속도, 재질 등 여러 요소에 따라 달라집니다. 하지만 정답이 하나로 정해져 있는 것이 아니기 때문에 오히려 창작의 여지가 더 많아집니다.
애니메이션 CSS가 헷갈린다면 지속 시간과 transform translate 속성을 직접 만져보세요. 조금만 연습하면 각 요소가 어떻게 연결되는지 훨씬 쉽게 이해할 수 있습니다.
- 40% 키프레임의 transform translate 값을 -48px로 바꿔보고 어떤 변화가 생기는지 확인해 보세요.
- CSS
animation속성의 지속 시간을 2초 대신 5초로 바꿔보세요. 그다음에는 100ms로도 바꿔보세요 (초 대신 밀리초 단위도 사용할 수 있습니다).
극단적인 값으로 실험해 보면 개념을 훨씬 쉽게 이해할 수 있습니다. 저 역시 '아하!' 하는 순간은 대부분 그럴 때 찾아옵니다.
직접 실험해 보세요!
CSS 애니메이션은 무궁무진한 가능성을 가지고 있습니다. 기존 애니메이션에 적용할 수 있는 몇 가지 변형을 간단히 살펴보겠습니다.
animation-delay 속성
지금은 웹페이지가 로드되자마자 화살표가 튀기 시작합니다. 사용자가 사이트에 진입한 직후부터 방해받지 않도록 애니메이션 시작을 약간 늦추고 싶을 수 있습니다.
그럴 때는 .bounce 클래스에 animation-delay 속성을 다음과 같이 추가하면 됩니다.
.bounce {
animation: bounce 2s;
animation-delay: 5s;
}
이제 2초짜리 키프레임 애니메이션은 페이지가 로드된 후 정확히 5초가 지난 뒤에야 시작됩니다.
animation-iteration-count 속성
애니메이션을 여러 번 반복하고 싶을 때가 있습니다. 반복하려면 animation-iteration-count 속성을 다음과 같이 사용합니다.
.bounce {
animation: bounce 2s;
animation-delay: 5s;
animation-iteration-count: 2;
}
이제 화살표는 5초 후에 튀기 시작하고, 이번에는 키프레임 애니메이션이 한 번 더 반복됩니다.
무한 반복 CSS 애니메이션
드문 경우지만 CSS 애니메이션을 무한히 실행하고 싶을 때가 있습니다. 그럴 때는 반복 횟수를 infinite;로 변경하면 됩니다.
.bounce {
animation: bounce 2s;
animation-iteration-count: infinite;
}
다만 무한 애니메이션은 신중하게 사용하세요. 영원히 빙글빙글 도는 애니메이션을 좋아하는 사람은 없습니다.
예외적인 경우라면 은은하게 깜빡이는 수많은 작은 별들로 이루어진 살아 있는 듯한 배경 화면 정도입니다. 이런 목적이라면 분위기를 역동적으로 유지하기 위해 애니메이션을 반복 실행하는 것이 합리적입니다.
Autoprefixer 활용하기
이 코드를 모든 최신 브라우저에서 작동하게 하려면 autoprefixer를 사용해야 합니다. 여기서는 코드를 짧고 읽기 쉽게 유지하기 위해 접두사를 붙인 속성들을 포함하지 않았습니다. 해당 CodePen에 접속하면 접두사가 붙은 속성을 포함한 전체 코드를 확인할 수 있습니다.
CSS 애니메이션 학습 자료
- MDN Web Docs: CSS Animation