CSS 로딩 스피너, 이미지 없이 무한 회전하는 원리

웹사이트에서 로딩 중에 화면 가운데서 빙글빙글 도는 스피너를 보면 애니메이션 동영상이나 GIF 파일이라고 생각하기 쉽습니다. 하지만 대부분의 스피너는 이미지 파일 하나 없이 CSS 테두리 색과 회전 애니메이션 몇 줄만으로 만들어집니다. 원리를 알면 색과 속도를 바꿔 원하는 스피너를 직접 만들 수 있습니다.
요약 ① 스피너는 원 테두리 중 한쪽만 다른 색으로 칠해서 만든 정지 도형입니다 ② keyframes로 0도에서 360도까지 회전 각도만 정의하면 브라우저가 나머지를 자동으로 그립니다 ③ animation 속성에 infinite를 붙이면 회전이 끝나지 않고 계속 반복됩니다
CSS 스피너가 이미지 없이 도는 이유 — 왜 이런 일이 생기나
화면에서 도는 로딩 스피너는 움직이는 이미지 파일이 아니라 정지된 도형 하나를 계속 회전시키는 것뿐입니다. 도형 자체는 한 번도 바뀌지 않고, transform: rotate() 각도 값만 0도에서 360도로 계속 바뀌면서 도는 것처럼 보이는 착시입니다.
가장 흔한 링 스피너는 원 하나의 테두리(border) 중 위쪽 한 변만 진한 색을 칠해서 만듭니다. 나머지 세 변은 옅은 색이나 투명하게 두면, 진한 색 부분이 원을 따라 돌 때마다 진행되고 있다는 느낌을 줍니다.
이 회전을 계속 반복시키는 역할은 CSS의 keyframes와 animation 속성이 맡습니다. 시작과 끝 각도만 정의해두면 브라우저가 그 사이 각도를 자동으로 계산해 부드럽게 이어 그리기 때문에, 별도의 프레임 이미지가 여러 장 필요하지 않습니다.
무한 회전 스피너 만들기 — 확인/해결 방법
직접 만들 때는 먼저 정사각형 하나를 준비합니다. 너비와 높이를 같은 값으로 맞추고 border-radius를 50%로 주면 완전한 원이 됩니다.
테두리는 border로 전체를 옅은 색으로 두르되, border-top-color만 따로 진한 색으로 지정합니다. 이렇게 하면 원의 위쪽 한 지점만 색이 다른 도형이 만들어집니다.
다음은 keyframes로 회전 각도를 정의할 차례입니다. 끝 지점에 transform: rotate(360deg)만 적어주면 브라우저가 0도부터 360도까지 자동으로 채워 그립니다.
마지막으로 animation 속성에 이 키프레임 이름과 지속 시간, 일정한 속도를 뜻하는 linear, 그리고 infinite를 함께 적어주면 한 바퀴가 끝난 뒤에도 멈추지 않고 처음부터 다시 반복됩니다. 원 모양, 테두리 색 차이, 회전 keyframes, infinite 반복 — 이 네 가지만 있으면 어떤 링 스피너든 직접 만들 수 있습니다.
저희 도구로 확인하기. 매번 테두리 색과 각도 값을 손으로 맞추는 대신, 스타일과 색·크기·속도를 슬라이더로 조절하며 완성된 HTML과 CSS를 바로 복사할 수 있습니다.
무료 · 가입 불필요 · 브라우저에서 바로 스피너 CSS 복사

자주 막히는 지점
| 상황 | 원인 |
|---|---|
| 스피너가 한 바퀴 돌고 멈춤 | animation 속성에 infinite를 빠뜨림 |
| 원이 통째로 한 가지 색으로만 보임 | border 네 변에 같은 색을 줘서 진한 부분과 옅은 부분의 구분이 사라짐 |
| 붙여넣었는데 가운데 정렬이 안 됨 | 감싸는 요소에 display: flex와 justify-content: center가 빠짐 |
| 점 3개·막대 스타일에서 다 같이 움직임 | 각 요소의 animation-delay 값이 달라야 순서대로 움직이는 것처럼 보임 |
표에 정리된 것처럼, 스피너가 멈추거나 어색해 보이는 원인은 대부분 animation 속성 하나를 빠뜨렸는지, 색을 구분해뒀는지로 좁혀집니다.
정리
로딩 스피너는 이미지나 동영상이 아니라 원 테두리의 색 차이와 회전 keyframes, infinite 반복만으로 만들어지는 착시입니다. 이 원리를 알면 색이나 속도가 다른 새 스피너가 필요할 때마다 값 몇 개만 바꾸면 됩니다.
직접 계산하고 값을 맞추는 대신, 스타일을 고르고 슬라이더로 조절하면서 바로 완성된 코드를 받아 쓰는 방법도 있습니다.
무료 · 가입 불필요 · 브라우저에서 바로 스피너 CSS 복사
자주 묻는 질문
로딩 스피너를 GIF나 동영상으로 만드는 것과 CSS로 만드는 것은 어떤 차이가 있나요?
GIF나 동영상은 별도 파일을 내려받아야 해서 로딩 자체를 더 느리게 만들 수 있습니다. CSS 스피너는 이미지 파일 없이 코드 몇 줄로 처리되기 때문에 페이지 용량에 영향을 주지 않습니다.
스피너 회전 속도는 어떻게 조절하나요?
animation 속성에 지정하는 지속 시간(초) 값을 줄이면 더 빠르게 돌고, 늘리면 더 느리게 돕니다. 보통 0.6초에서 1.5초 사이가 부자연스럽지 않게 보입니다.
점 3개나 막대 스타일도 링 스피너와 같은 원리인가요?
회전 대신 각 점이나 막대의 크기·투명도가 순서대로 바뀌는 keyframes를 씁니다. animation-delay 값을 요소마다 조금씩 다르게 줘서 동시에 움직이지 않고 순서대로 움직이는 것처럼 보이게 만듭니다.
