본문 바로가기
WEB Basic/HTML & CSS

HTML과 CSS로 로딩 스피너 만들기: 부드러운 로딩 애니메이션 구현

by Devinus 2024. 1. 15.

1. 구현 결과 미리보기

페이지가 로딩 중입니다...

2. 분석

로딩 스피너의 중요성

  • 웹 페이지나 웹 애플리케이션에서 사용자에게 컨텐츠가 로딩 중임을 시각적으로 알려주는 로딩 스피너는 사용자 경험을 향상시키는 데 중요한 역할을 합니다. 특히, 네트워크 속도가 느릴 때 사용자는 페이지 로딩이 진행 중인지를 인지하고 있어야 합니다.

로딩 스피너의 역할과 사용 기술 소개

  • 로딩 스피너는 주로 네트워크 요청, 데이터 로딩, 페이지 전환 등의 작업이 이뤄지는 동안 화면에 표시됩니다. 주로 사용되는 기술로는 CSS 애니메이션과 트랜지션입니다. 이러한 기술을 통해 로딩 스피너는 부드럽게 회전하면서 사용자에게 로딩 중임을 시각적으로 알려줍니다.

전체 화면 덮는 역할

/* style.css */
.loading-wrap {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    background-color: #0002;
    position: fixed;
}

`width: 100%;`, `height: 100%;`, `position: fixed;`를 통해 항상 화면 위에 존재하도록 하여 로딩되는 순간 다른 요소들을 숨깁니다.

 

애니메이션

`@keyframes`라는 키워드를 활용해서 애니메이션을 생성합니다. 생성한 애니메이션은 한 번 할당해놓고 변수처럼 재사용 가능하며, 애니메이션을 발생시키고 싶은 요소에서 `animation: rotate 1s infinite;`와 같이 효과를 줄 수 있습니다.

애니메이션 프로퍼티에 대한 더 자세한 정보는 다음을 참고하십시오: https://developer.mozilla.org/ko/docs/Web/CSS/animation

/* style.css */
@keyframes rotate {
    from {
      transform: rotate(0deg);
    }
    to {
      transform: rotate(360deg);
    }
}
.loading-spinner {
    /*
    ...css code
    */
    animation: rotate 1s linear infinite;
}

 

 

로딩 완료

로딩 스피너의 나타남과 사라짐은 JavaScript로 조작합니다. 통상적으로 데이터 패치(fetch)로 요청 시 로딩 나타남, 화면에 나타나는 요소들(ex; 글 목록)의 로드 결과가 마무리 되면 로딩 사라짐 흐름을 갖습니다.

 

다음은 버튼을 눌렀을 때 로딩이 나타났다가 1초 뒤에 사라지는 예시입니다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
    .loading-wrap {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        width: 100%;
        height: 300px;
        background-color: #0002;
    }
    .loading-spinner {
        width: 40px;
        height: 40px;
        border: 5px solid #3498db;
        border-top: 5px solid transparent;
        border-radius: 50%;
        animation: rotate 1s linear infinite;
    }

    @keyframes rotate {
        from { transform: rotate(0deg); }
        to { transform: rotate(360deg); }
    }
      .ex-box {
        padding: 10px;
        border: 1px solid black;
      }
    </style>
</head>
<body>
    <div class="ex-box">
      <button id="loadingButton" onclick="simulateLoading()">로딩 시작</button>
      <div class="loading-wrap loading-wrap--js" style="display: none">
        <div class="loading-spinner loading-spinner--js"></div>
        <p id="loadingMessage"></p>
      </div>
    </div>
    <script>
      function simulateLoading() {
        var loadingSpinner = document.querySelector(".loading-wrap--js");
        var loadingMessage = document.getElementById("loadingMessage");

        // 로딩 시작
        loadingSpinner.style.display = "flex";
        loadingMessage.textContent = "로딩 중...";

        // 1초 뒤에 로딩 완료
        setTimeout(function () {
          loadingSpinner.style.display = "none";
          loadingMessage.textContent = "로딩 완료";
        }, 1000);
      }
    </script>
</body>
</html>

3. 구현

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Loading Spinner</title>
    <link rel="stylesheet" href="styles.css" />
    <style>
      .loading-wrap {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        width: 100%;
        height: 100%;
        background-color: #0002;
        position: fixed;
      }
      .loading-spinner {
        width: 40px;
        height: 40px;
        border: 5px solid #3498db;
        border-top: 5px solid transparent;
        border-radius: 50%;
        animation: rotate 1s linear infinite;
      }

      @keyframes rotate {
        from {
          transform: rotate(0deg);
        }
        to {
          transform: rotate(360deg);
        }
      }
    </style>
  </head>
  <body>
    <div class="loading-wrap">
      <div class="loading-spinner"></div>
      <p>페이지가 로딩 중입니다...</p>
    </div>
  </body>
</html>

4. 참고 자료

pure css loader: https://loading.io/css/

MDN - animation : https://developer.mozilla.org/ko/docs/Web/CSS/animation