페이스북이나 유튜브의 첫 화면을 보면, 아주 잠깐 프레임을 그려주는 빈 페이지를 확인할 수 있는데요. 이러한 페이지를 개발에서 skeleton screen(스켈레톤 스크린) 이라고 합니다. 저도 함께 일하는 개발자를 통해서 처음 알게 되었는데, skeleton은 뼈대를 의미하는 단어네요. skeleton screen을 적용하면 사용자가 “대기중”이라는 느낌을 전달하면서 빠르게 로드되고 있다고 인식하게 합니다.

그럼 이러한 UI는 어떤 방법으로 구현할 수 있을까요? CSS의 linear-gradient 속성과 :empty 선택자를 활용하여 이를 구현해 보도록 하겠습니다.

1. linear-gradient 원리

linear-gradient의 기본 문법은 아래와 같습니다.

선형 linear-gradient(angle, color-stop1, color-stop2);
원형 radial-gradient(shape size at position, start-color, ..., last-color);

선형을 적용해보면, 방향과 적용 컬러를 순서대로 선언하게 됩니다. 방향 to bottom은 기본 값으로 생략이 가능합니다.
linear-gradient(to bottom, yellow 20%, steelblue 50%)

보통은 부드럽게 컬러가 변할 때 많이 쓰는 속성이지만, 경계면이 매끄럽게 떨어지도록 만드는 방법도 있습니다. 첫 번째와 두 번째 위치값이 동일할 경우, 경계선이 만나면서 그라데이션 영역이 사라지므로 아래와 같이 단색 면이 됩니다.
linear-gradient(yellow 50%, steelblue 50%)

또한 두 번째 값이 첫 번째의 값보다 클 때(더 위쪽에 위치할 때) 도 브라우저는 동일하게 동작하는데요,
두 번째 위치를 0으로 잡았다면 그 위치는 브라우저에 의해 이전 색상 정지의 위치와 같게 그 위치가 조정됩니다.
linear-gradient(yellow 50%, steelblue 0) = linear-gradient(yellow 50%, steelblue 50%)
두 번째 값이 투명할 경우에는? 첫 번째 색으로만 표현됩니다.
linear-gradient(yellow 50%, transparent 0)

이러한 속성을 활용하면 하나의 div에 background-image로 도형을 드로잉해 볼 수 있습니다.

2. linear-gradient를 활용한 도형 드로잉

<실습 예제>


background-image 속성은 <image> <position> <size>의 값을 주어서 컨트롤할 수 있습니다.

1) background-image : 멀티 배경 지정

background-image 속성은 여러 배경 이미지를 추가할 수 있습니다 .
서로 다른 배경 이미지는 쉼표로 구분되며 이미지는 서로 위에 겹쳐서 표시됩니다.
원형 1개, 사각형 4개를 그리기 위해서 5번 선언해 주었고, y축으로 반복할 수 있게 repeat-y를 주었습니다.

background-image:
  radial-gradient( circle 50px at 50px 50px, gray 99%, transparent 0 ), /* 원형 */
  linear-gradient( lightgray 20px, transparent 0 ), /* 사각1 */
  linear-gradient( lightgray 20px, transparent 0 ), /* 사각2 */
  linear-gradient( lightgray 20px, transparent 0 ), /* 사각3 */
  linear-gradient( lightgray 20px, transparent 0 ); /* 사각4 */
background-repeat: repeat-y;

2) background-position : 위치 지정

겹쳐 있는 각 도형의 위치를 x축, y축으로 재지정해줍니다.

background-position:
   0 0,         /* 원형 */
   120px 0,     /* 사각1 */
   120px 40px,  /* 사각2 */
   120px 80px,  /* 사각3 */
   120px 120px; /* 사각4 */

3) background-size : 사이즈 지정

각 도형에 원하는 사이즈 width, height 값을 지정해줍니다.

background-size:
  100px 200px, /* 원형 */
  150px 200px, /* 사각1 */
  350px 200px, /* 사각2 */
  300px 200px, /* 사각3 */
  250px 200px; /* 사각4 */

4) animation 레이어 추가

빛이 지나가는 듯한 움직임을 위해 흰색 그라데이션의 이미지와 keyframe animation을 추가하면 효과를 표현할 수 있습니다.
다만 주의할 점은, multi background의 경우에 쌓임맥락은 z-index와 약간 다르다는 점입니다. (참고 : stacking-order-of-multiple-backgrounds)
하나의 요소 안에서 이루어지기 때문에 먼저 선언할수록 위쪽으로 쌓이게 되는데요.
지금까지 만든 도형보다 위쪽에 레이어를 선언해주면 됩니다.

background-image:
  linear-gradient( 100deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.5) 50%, rgba(255, 255, 255, 0)  80% ), /* animation */
  radial-gradient( circle 50px at 50px 50px, gray 99%, transparent 0 ), /* 원형 */
  linear-gradient( lightgray 20px, transparent 0 ), /* 사각1 */
  linear-gradient( lightgray 20px, transparent 0 ), /* 사각2 */
  ...
background-size:
  50px 200px,  /* animation */
  100px 200px, /* 원형 */
  150px 200px, /* 사각1 */
  350px 200px, /* 사각2 */
  ...

5) :empty 선택자 활용

데이터가 들어오기 전에 빈 태그 상태를 :empty 선택자로 선택할 수 있습니다.
:empty는 자식(텍스트 노드 포함)이 전혀 없는 요소에 적용하는 선택자입니다.
데이터 로딩 이전에 태그를 그리지 않은 상태일 경우에 활용 가능하겠습니다.
.skeleton-screen:empty {}

3. 장점 및 활용범위

단 하나의 태그에서 CSS 만으로 그려질 수 있다는 점에서 코드가 간단하며 변형 및 확장이 용이합니다.
또한 background-image 속성은 렌더링 시, layout 변동 없이 paint, composite 과정만 거치기 때문에 성능적으로도 이점이 있을 것으로 보입니다.
이를 응용하면 CSS를 활용한 패턴 제작 및 로딩아이콘차트 등의 다양한 드로잉도 시도해 볼 수 있습니다.
background-image 속성의 브라우저 범위는 IE10 이상으로, 대응 범위를 확인하여 문법을 작성해야 하며 -webkit-, -moz-, -ms- and -o-의 벤더 프리픽스를 필요로 합니다.


0개의 댓글

답글 남기기

아바타 플레이스홀더

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다