Article 서비스에서는 콘텐츠 로딩 시 애니메이션을 포함한 스켈레톤 UI를 적용하고 있습니다.
일반적인 스켈레톤 UI와는 다른 디자인 스펙을 구현하는 과정에서 고민했던 부분들을 정리하여 소개하려고 합니다.
1. 아티클 서비스의 스켈레톤 디자인 스펙

스켈레톤은 사용자에게 페이지가 로드되고 있다는 것을 알려주기 위해 실제 페이지의 요소와 비슷한 빈 요소입니다.
a) 반응형 디자인
Article 서비스는 반응형 레이아웃을 기반으로 하기 때문에 스켈레톤도 반응형으로 제작해야 합니다.
| 서비스 | 스켈레톤 | |
|---|---|---|
| 모바일 | ![]() ![]() | ![]() ![]() |
| PC | ![]() | ![]() |
b) 전역 애니메이션
스켈레톤이 표시 중일 때, 전역으로 배경이 위에서 아래로 흐르는듯한 효과의 애니메이션을 적용해야 합니다.

위와 같은 애니메이션을 적용하기 위해서 각각의 스켈레톤 요소에 애니메이션 delay를 설정하려고 했지만, 화면 크기에 따라 delay 값이 달라져야 하기 때문에 전역으로 애니메이션을 설정할 수 있는 다른 방법을 찾아야 했습니다.
2. 스켈레톤 구현하기
애니메이션을 설정하기 전에, 먼저 스켈레톤 요소를 만들고 디자인을 적용합니다.
| 스켈레톤 요소 생성 | 각 요소에 반응형 스타일 적용 |
|---|---|
![]() ![]() | ![]() ![]() |
// 공통 스켈레톤 스타일
.skeleton {
position: relative;
overflow: hidden;
background-color: #eee;
}
// 개별 스타일
.type_pill {
border-radius: 100px;
}
.type_rectangle {
border-radius: 10px;
}
...
a) background-attachment 로 배경 애니메이션 구현하기
background-attachment: scroll | background-attachment: fixed |
|---|---|
![]() | ![]() |
background-attachment 속성은 스크롤 시 배경이 어떻게 변할지 제어하는 속성입니다. 기본 값인 scroll은 스크롤 시 배경이 같이 스크롤 되지만 fixed 값을 사용하면 스크롤을 하더라도 배경은 그대로 유지가 됩니다.
또한 fixed 값 사용 시 배경의 위치가 요소 기준이 아니라 viewport 기준으로 설정되는데, 이 특징이 스켈레톤 애니메이션을 구현하는데 적합하다고 생각했습니다.
위에서 만든 스켈레톤에 ::after 요소를 만들어서 그라디언트 배경을 설정합니다. 여기에 background-attachment: fixed를 적용합니다.

.skeleton::after {
position: absolute;
inset: 0;
background-attachment: fixed;
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0px, rgba(0, 0, 0, 0.15) 145px, rgba(0, 0, 0, 0) 290px);
content: '';
}
위와 같이 작성하면 스켈레톤 요소에 같은 그라디언트 배경이 적용되고, 스켈레톤 요소의 overflow: hidden으로 그라디언트 배경이 요소 내부 영역에만 노출됩니다.
그다음 그라디언트 배경 요소에 애니메이션을 적용합니다.

.skeleton::after {
animation: flow 1.5s linear 1s infinite forwards;
}
@keyframes flow {
0% {
background-position-y: -290px;
}
33% {
background-position-y: calc(100vh + 290px);
}
100% {
background-position-y: calc(100vh + 290px);
}
}
background-position-y 값이 올라갈수록 그라디언트 배경이 아래로 내려갑니다.
애니메이션은 각 스켈레톤 요소에 적용되지만, background-attachment: fixed가 적용되어 있어서 모든 스켈레톤 요소의 background-position-y가 viewport로 같기 때문에 위에서 아래로 흐르는듯한 효과를 보여줄 수 있습니다.
b) 아이콘 모양으로 스켈레톤 만들기
| 서비스 | 스켈레톤 |
|---|---|
![]() ![]() | ![]() |
스켈레톤 중 별 모양과 같이 CSS 만으로 표현하기 어려운 모양은 mask-image 속성으로 마스크 이미지를 적용했습니다.
요소에 마스크 이미지를 적용하면 이미지의 검은색 부분만 요소가 보이고 나머지 부분을 투명하게 만들어줍니다.
.skeleton.star { mask-image: url(~/src/assets/svg/IconStar.svg); }
| 스켈레톤 요소 | 마스크 이미지 | 마스크 적용된 스켈레톤 |
|---|---|---|
![]() | ![]() | ![]() |
c) linear-gradient과 radial-gradient로 다양한 모양 만들기
svg 이미지를 mask-image로 활용한 것처럼 linear-gradient, radial-gradient로 이미지를 만들어서 mask-image로 활용하는 것이 가능합니다.
CSS 코드로 만들 수 있는 간단한 도형이나 패턴은 svg 이미지를 제작하지 않고 아래와 같이 적용했습니다.
격자

repeating-linear-gradient 속성으로 격자를 만들 수 있습니다.
.skeleton {
mask-image:
// 가로줄
repeating-linear-gradient(to bottom, #000 0px 1px, transparent 1px 15px),
// 세로줄
repeating-linear-gradient(to right, #000 0px 1px, transparent 1px 15px);
}
요소 내부의 요소
Article Post 스켈레톤 디자인은 border-radius 3px, border-width 1px 요소 내부에 다른 요소가 있습니다.

background-attachment: fixed를 사용한 스켈레톤 구조에서는 위 모양처럼 요소 내부에 다른 요소를 추가할 수 없습니다. 따라서 테두리를 나누어서 각각 다른 요소로 구현했습니다.

테두리의 직선 부분은 사각형 모양이라서 width, height 만으로 구현이 가능했지만 모서리 부분은 radial-gradient로 이미지를 만들어서 mask-image에 적용했습니다.
먼저 radial-gradient로 90도 부채꼴 도형을 만듭니다. 이때, 반지름은 모서리의 border-radius 값으로 합니다.

.image { background-image: radial-gradient(farthest-side at top right, #000 3px, transparent); }
그다음, 모서리의 border-radius – border-width 값만큼 부채꼴 안쪽을 투명색으로 바꿔줍니다.

.image {
background-image: radial-gradient(farthest-side at top right, transparent 2px, #000 2px 3px, transparent);
}
우리가 원하는 모서리 mask-image를 만들었고 비슷한 방식으로 모든 부분의 모서리를 만들 수 있습니다.
3. 주의할 점
background-attachment: fixed가 적용된 요소의 상위 요소중 translateZ, translate3d를 가진 요소가 있는 경우 background-position이 viewport가 아니게 됩니다.
따라서 위 방식을 적용할 때 상위 요소중 translateZ 혹은 translate3d가 적용되어 있는지 확인 후 적용해야 합니다.
4. 마무리
background-attachment: fixed를 활용해서 전역 애니메이션을 구현할 수 있었습니다. 또한 mask-image 속성을 사용해서 요소를 원하는 이미지나 패턴 모양으로 잘라낼 수 있었습니다.
작업하실 때 비슷한 디자인이나 인터랙션 구현 시 도움이 되셨으면 좋겠습니다. 긴 글 읽어주셔서 감사합니다!
또, 문서 작성에 많은 도움을 주신 전혜영님에게 감사드립니다!
5. 참고 사이트
- MDN
background-attachment: https://developer.mozilla.org/en-US/docs/Web/CSS/background-attachment - MDN
mask-image: https://developer.mozilla.org/en-US/docs/Web/CSS/mask-image


















0개의 댓글