본문 바로가기
웹 퍼블리싱 | Web Publishing/로더 | Loader

웹사이트에 멋진 로딩 화면 만들기: 단계별 가이드

by 테드 창 2025. 6. 26.
728x90

로딩 되는 예시 이미지

사용자 경험을 향상시키는 가장 간단하면서도 효과적인 방법 중 하나는 바로 로딩 화면입니다. 페이지가 로드되는 동안 사용자에게 시각적 피드백을 제공하면, 기다리는 시간이 지루하지 않게 느껴지죠. 오늘은 HTML, CSS, JavaScript만으로 프로페셔널한 로딩 화면을 만드는 방법을 알아보겠습니다.

1. 기본 구조 설정하기

먼저 로더의 기본 HTML 구조를 잡아보겠습니다. 로더 컨테이너와 메인 콘텐츠를 분리하여 구성합니다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>사이트 로더</title>
</head>
<body>
    <!-- 로더 화면 -->
    <div class="loader-container" id="loader">
        <div class="loader">
            <div class="spinner"></div>
        </div>
        <div class="loading-text">
            로딩 중<span class="dots">...</span>
        </div>
        <div class="progress-bar">
            <div class="progress-fill"></div>
        </div>
    </div>

    <!-- 메인 콘텐츠 -->
    <div class="main-content" id="mainContent">
        <h1 class="welcome-text">환영합니다!</h1>
        <p class="sub-text">사이트가 성공적으로 로드되었습니다.</p>
    </div>
</body>
</html>

이 구조에서 .loader-container는 전체 화면을 덮는 로더 영역이고, .main-content는 로딩이 완료된 후 보여질 실제 콘텐츠입니다. 로더는 스피너, 텍스트, 프로그레스 바로 구성되어 있어 다층적인 시각적 효과를 제공합니다.

2. CSS로 스타일링과 애니메이션 구현하기

이제 로더에 생명을 불어넣을 CSS를 작성해보겠습니다. 그라데이션 배경과 다양한 애니메이션 효과를 구현합니다.

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

.loader-container {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
    z-index: 9999;
    transition: opacity 0.5s ease-out, visibility 0.5s ease-out;
}

.loader-container.hidden {
    opacity: 0;
    visibility: hidden;
}

.loader {
    position: relative;
    width: 80px;
    height: 80px;
    margin-bottom: 30px;
}

/* 맥동 효과 */
.loader::before,
.loader::after {
    content: '';
    position: absolute;
    border-radius: 50%;
    animation: pulsate 2s infinite ease-in-out;
}

.loader::before {
    width: 100%;
    height: 100%;
    background: rgba(255, 255, 255, 0.3);
    animation-delay: -1s;
}

.loader::after {
    width: 60%;
    height: 60%;
    background: rgba(255, 255, 255, 0.6);
    top: 20%;
    left: 20%;
}

/* 회전 스피너 */
.spinner {
    position: absolute;
    width: 100%;
    height: 100%;
    border: 3px solid transparent;
    border-top: 3px solid #ffffff;
    border-radius: 50%;
    animation: spin 1s linear infinite;
}

/* 프로그레스 바 */
.progress-bar {
    width: 200px;
    height: 4px;
    background: rgba(255, 255, 255, 0.2);
    border-radius: 2px;
    margin-top: 20px;
    overflow: hidden;
}

.progress-fill {
    height: 100%;
    background: linear-gradient(90deg, #ffffff, #f0f0f0, #ffffff);
    border-radius: 2px;
    width: 0%;
    animation: fillProgress 3s ease-out forwards;
}

/* 애니메이션 키프레임 */
@keyframes pulsate {
    0%, 100% {
        transform: scale(0.8);
        opacity: 0.5;
    }
    50% {
        transform: scale(1.2);
        opacity: 1;
    }
}

@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

@keyframes fillProgress {
    0% { width: 0%; }
    100% { width: 100%; }
}

여기서 핵심은 세 가지 애니메이션입니다. pulsate는 원형 요소들이 맥동하는 효과, spin은 스피너가 회전하는 효과, fillProgress는 프로그레스 바가 채워지는 효과를 만듭니다. ::before와 ::after 가상 요소를 활용해 겹겹이 쌓인 원형 효과를 구현한 것도 포인트입니다.

3. JavaScript로 동적 기능 추가하기

정적인 애니메이션에 동적인 요소를 더해봅시다. 로딩 텍스트가 단계별로 변경되고, 실제 페이지 로드 완료를 감지하는 기능을 구현합니다.

// 로딩 시뮬레이션
const loadingTexts = [
    '로딩 중...',
    '데이터 불러오는 중...',
    '거의 완료...',
    '완료!'
];

let textIndex = 0;
const loadingTextElement = document.querySelector('.loading-text');

// 텍스트 변경 애니메이션
const textInterval = setInterval(() => {
    if (textIndex < loadingTexts.length - 1) {
        textIndex++;
        loadingTextElement.innerHTML = loadingTexts[textIndex] + '<span class="dots">...</span>';
    }
}, 800);

// 로딩 완료 후 메인 콘텐츠 표시
setTimeout(() => {
    clearInterval(textInterval);
    
    // 로더 숨기기
    const loader = document.getElementById('loader');
    loader.classList.add('hidden');
    
    // 메인 콘텐츠 표시
    setTimeout(() => {
        const mainContent = document.getElementById('mainContent');
        mainContent.classList.add('visible');
    }, 500);
    
}, 3200);

// 실제 사용시 페이지 로드 완료 감지
window.addEventListener('load', function() {
    setTimeout(() => {
        const loader = document.getElementById('loader');
        loader.classList.add('hidden');
        
        setTimeout(() => {
            const mainContent = document.getElementById('mainContent');
            mainContent.classList.add('visible');
        }, 500);
    }, 1000); // 최소 1초는 로더 표시
});

JavaScript에서는 setInterval을 사용해 0.8초마다 로딩 텍스트를 변경합니다. 실제 운영 환경에서는 window.addEventListener('load')를 사용해 페이지의 모든 리소스가 로드될 때까지 기다린 후 로더를 숨기는 것이 좋습니다. 최소 1초 정도는 로더를 보여주어 너무 빠르게 사라지지 않도록 하는 것도 UX 측면에서 중요합니다.

4. 반응형 디자인과 커스터마이징 팁

마지막으로 다양한 디바이스에서 잘 보이도록 반응형 처리를 하고, 커스터마이징할 수 있는 부분들을 알아보겠습니다.

/* 반응형 디자인 */
@media (max-width: 768px) {
    .loader {
        width: 60px;
        height: 60px;
    }
    
    .loading-text {
        font-size: 16px;
    }
    
    .progress-bar {
        width: 150px;
    }
    
    .welcome-text {
        font-size: 36px;
    }
    
    .sub-text {
        font-size: 16px;
        padding: 0 20px;
    }
}

/* 커스텀 색상 테마 */
.loader-container.dark-theme {
    background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%);
}

.loader-container.vibrant-theme {
    background: linear-gradient(135deg, #ff6b6b 0%, #4ecdc4 100%);
}

반응형 디자인에서는 모바일 화면에서 요소들의 크기를 적절히 줄여 가독성을 유지합니다. 색상 테마를 쉽게 변경할 수 있도록 CSS 클래스를 추가로 정의해두면, JavaScript로 동적으로 테마를 변경할 수도 있습니다.

커스터마이징 포인트:

  • background 속성으로 배경 그라데이션 색상 변경
  • 애니메이션 duration과 timing-function 조절로 속도감 변경
  • loadingTexts 배열 수정으로 로딩 메시지 개인화
  • CSS 변수를 활용한 테마 시스템 구축

이제 여러분만의 독특한 로딩 화면을 만들어보세요! 사용자들이 기다리는 시간도 즐거운 경험이 될 수 있습니다.

📁 완성된 예시 파일

위에서 설명한 모든 기능이 포함된 완전한 HTML 파일을 확인하고 싶으시면, 밑에 파일을 다운로드해서 확인해주세요~

로딩화면만들기_예시.html
0.01MB

728x90