티스토리 뷰

이 TisTory(#1) 간단하게 로딩 창 구현하기 포스팅은 Tistory(#1) theme toggle 구현하기를 일부 공유합니다.

html

<!--loading-->
<div id="loading">
  <div id="loading-circle">
    <div id="loading-empty"></div>
  </div>
</div>
<!--loading-->

html 코드는 크게 3개의 요소로 이루어집니다.

  1. #loading → loading 화면 전체
  2. #loading-circle → loading을 의미하는 원
  3. #loading-empty → #loading-circle에서 원의 미완성 부분

loading.css

#loading {
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 32;
  position: fixed;
  top: 0;
  width: 100vw;
  height: 100vh;
  background-color: var(--background-color-body);
  animation: hideLoadingScreen 0.3s linear forwards;
  animation-delay: 0.7s;
}

@keyframes hideLoadingScreen {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
    visibility: hidden;
  }
}

#loading-circle {
  position: relative;
  width: 2rem;
  height: 2rem;
  border: 0.3rem solid var(--color-a);
  border-radius: 50%;
  display: flex;
  justify-content: center;
  animation: loadingCircle 1s ease-in-out infinite;
}

@keyframes loadingCircle {
  from {
    transform: none;
  }
  to {
    transform: rotate(360deg);
  }
}

#loading-empty {
  position: absolute;
  background-color: var(--background-color-body);
  width: 1rem;
  height: 2rem;
  top: -1rem;
}

#loading

#loading {
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 32;
  position: fixed;
  top: 0;
  width: 100vw;
  height: 100vh;
  background-color: var(--background-color-body);
  animation: hideLoadingScreen 0.3s linear forwards;
  animation-delay: 0.7s;
}

#loading의 역활은 loading 전체화면입니다.

width, height

#loading {
  width: 100vw;
  height: 100vh;
}

너비(width)와 높이(height)를 각각 100vw 100vh로 설정하여 화면 전체가 해당되게 합니다.

display

#loading {
  display: flex;
  justify-content: center;
  align-items: center;
}

displayflexible하게 만듭니다. 기본 축(justify-content)과 교차 축(align-items) center로 해 자식 요소가 화면의 정중앙에 오도록 합니다.

z-index

#loading {
  z-index: 32;
}

z-index 속성을 32로 하여 현재 레이어 층이 32층이며 가장 최상위 층이라고 설정합니다. 최상위 층이라는 것은 곧 이 loading 창 위에 아무것도 없다는 것입니다.

position

#loading {
  position: fixed;
  top: 0;
}

positionfixed로 하여 요소를 일반적인 흐름에서 제거하고, 공간 또한 배정하지 않게 한 후 top: 0을 통해 전체 화면의 최상단에 위치하게 합니다.

animation

#loading {
  animation: hideLoadingScreen 0.3s linear forwards;
  animation-delay: 0.7s;
}

hideLoadingScreen 애니메이션을 0.3초(animation-duration)동안 실행하고 애니메이션 진행 방식(animation-timing-function)을 linear 즉 선형성 직선적으로 바르게 진행하도록 합니다. 그리고 forwards 속성을 줌으로(animation-fill-mode) 애니메이션이 끝난 후에도 지속되게 합니다.

또한 애니메이션 지연(animation-delay)을 0.7초로 하여 애니메이션이 0.7초 뒤에 실행하도록 합니다.

hideLoadingScreen animation

@keyframes hideLoadingScreen {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
    visibility: hidden;
  }
}

@keyframes 규칙을 생성합니다. 애니메이션 이름(animation-name)을 hideLoadingScreen으로 정합니다. opacity를 통해 불투명 정도를 완전히 없음(1) 에서 완전히 있음(0) 으로 합니다. 하지만 불투명할 뿐이지 존재하므로 요소의 보임(visibility)을 hidden으로 숨김처리 하여 loading 창이 없는 효과를 줘 loading 창 밑 층에 있는 요소들을 제어 할 수 있게 합니다.

#loading-circle

#loading-circle {
  position: relative;
  width: 2rem;
  height: 2rem;
  border: 0.3rem solid var(--color-a);
  border-radius: 50%;
  display: flex;
  justify-content: center;
  animation: loadingCircle 1s ease-in-out infinite;
}

#loading-circle 원에 관한 요소입니다.

position

#loading-circle {
  position: relative;

positionrelative로 설정하여 #loading-empty기준이 되는 조상#loading-circle 인 것이라고 지정합니다.

width, height

#loading-circle {
  width: 2rem;
  height: 2rem;
}

widthheight2rem으로 하여 px과 같은 절대적인 길이가 아닌 상대적인 길이 설정을 통해 웹과 모바일을 모두 호환이 가능하게끔 합니다.

border

#loading-circle {
  border: 0.3rem solid var(--color-a);
  border-radius: 50%;
}

마찬가지로 border의 굵기 또한 상대적인 척도인 rem을 사용합니다. 색상은 dataTheme.css--color-a#8b949e#57606a를 사용합니다. 그리고 border-radius는 원이 되어야 하므로 50% 로 합니다.

display

#loading-circle {
  display: flex;
  justify-content: center;
}

displayflexible 속성을 주고 justify-contentcenter로 설정해 자식 요소인 #loading-empty중앙으로 오게 합니다.

animation

#loading-circle {
  animation: loadingCircle 1s ease-in-out infinite;
}

loadingCircle 애니메이션을 1초(animation-duration)동안 실행하고 애니메이션 진행 방식(animation-timing-function)을 ease-in-out시작과 끝의 속도를 천천히 진행하도록 합니다. 그리고 infinite 속성을 줌으로(animation-fill-mode) 애니메이션이 끝나고도 계속 무한으로 반복되게 합니다.

loadingCircle animation

@keyframes loadingCircle {
  from {
    transform: none;
  }
  to {
    transform: rotate(360deg);
  }
}

@keyframes 규칙을 생성합니다. 애니메이션 이름(animation-name)을 loadingCircle로 정합니다. transformnone으로 설정하여 효과가 없는 상태에서 시작하여 rotate(360deg)360도로 시계방향으로 회전하게 합니다.

#loading-empty

#loading-empty {
  position: absolute;
  background-color: var(--background-color-body);
  width: 1rem;
  height: 2rem;
  top: -1rem;
}

width, height

#loading-empty {
  width: 1rem;
  height: 2rem;
}

너비(width)와 높이(height)를 1rem, 2rem으로 여유롭게 설정하여 원 상단의 일부분을 가리게 합니다.

position

#loading-empty {
  position: absolute;
  top: -1rem;
}

positionabsolute로 설정하여 가장 가까운 위치의 조상인 #loading-circle을 기준으로부터 top: -1rem1rem만큼 상단으로 위치가 이동합니다.

background-color

#loading-empty {
  background-color: var(--background-color-body);
}

background-color 즉 배경색은 themes.css--background-color-body#0d1117#57606a를 사용합니다.

'CSS' 카테고리의 다른 글

Tistory(#1) icon들을 CSS로 구현하기  (0) 2022.03.05
댓글