개발 같이해요/HTML&CSS

[ CSS ] 모바일 환경을 위한 다크모드 토글 만들기

Rio - Moon 2024. 2. 26. 16:55
728x90
반응형

 

스마트폰 사용이 일상화된 오늘날, 사용자들은 다양한 조명 환경에서 장시간 디바이스를 사용합니다. 이에 따라, 앱과 웹사이트의 다크모드 지원은 더 이상 선택이 아닌 필수가 되었습니다. 다크모드는 눈의 피로를 줄이고, 배터리 수명을 연장하는 등 여러 이점을 제공합니다. 이 포스팅 에서는 HTML, CSS, JavaScript를 사용하여 모바일 환경에 적합한 다크모드 토글 버튼을 만들어 보도록 하겠습니다.

이전포스팅에서 만들었던 다양한 작업을 아래 포스팅에서 확인 하실 수 있습니다.

 

 

모바일 환경에서 UI/UX 만들기 시리즈 


 

 


완성된 다크모드 토글 효과

이번 예제를 통해 완성 될 다크모드 토글 효과입니다.

다크모드 토글 효과

 

 


다크모드 토글 소스코드 구조 설명

 

DARKMODE  폴더 구조 입니다.

├── index.html

── css/

 │   └── style.css

└── js/

    └── script.js

 

 


 

다크모드 토글 HTML 구조 작성 - index.html 작성하기

 

html 출처

 

다크모드 토글 기능을 구현하기 위해, 먼저 기본적인 HTML 구조를 설정합니다.

index.html 에서 기본적인 화면 레이아웃 및 화면구조를 작성하도록 하겠습니다.

사용자가 버튼을 클릭하면 다크모드와 라이트모드를 전환할 수 있도록 토글 버튼을 포함합니다.

 

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>다크 모드 토글</title>
    <link rel="stylesheet" href="css/style.css">
    <!-- Font Awesome 아이콘 사용을 위한 CDN 링크. 필요에 따라 추가하세요. -->
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.3/css/all.css">
</head>
<body>
    <!-- 다크 모드 토글 스위치 -->
    <div class="toggle-switch">
        <input type="checkbox" id="darkModeToggle" class="checkbox">
        <label for="darkModeToggle" class="label">
            <i class="fas fa-sun"></i> <!-- 해 아이콘 -->
            <i class="fas fa-moon"></i> <!-- 달 아이콘 -->
            <div class="ball"></div> <!-- 토글 슬라이더 -->
        </label>
    </div>
    <div class="content">
        <h1>다크 모드 테스트</h1>
        <p>이 문장은 다크 모드와 라이트 모드에서 어떻게 보이는지 확인하기 위한 문장입니다.</p>
    </div>
    <script src="js/script.js"></script>
</body>
</html>

 

 


 

다크모드 토글 CSS 작성 - CSS / style.css 작성하기

 

css 출처

 

다음으로, CSS를 사용하여 토글 스위치와 페이지의 스타일을 정의합니다. 다크모드와 라이트모드에서의 배경색, 텍스트 색상, 그리고 토글 스위치의 디자인을 설정합니다.

 

:root {
    --background-color-light: #FFFFFF;
    --text-color-light: #000000;
    --toggle-background-light: #CCCCCC;
    --toggle-ball-light: #FFFFFF;

    --background-color-dark: #333333;
    --text-color-dark: #FFFFFF;
    --toggle-background-dark: #4D4D4D;
    --toggle-ball-dark: #FFFFFF;

    --font-size-base: 32px; /* 기본 텍스트 크기 */
    --font-size-large: 52px; /* 제목 등 큰 텍스트용 폰트 크기 */
}

body {
    background-color: var(--background-color);
    color: var(--text-color);
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    font-size: var(--font-size-base);
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
    height: 100vh;
    margin: 0;
    transition: background-color 0.3s, color 0.3s;
}

h1 {
    font-size: var(--font-size-large);
}

.dark-mode {
    --background-color: var(--background-color-dark);
    --text-color: var(--text-color-dark);
}

.toggle-switch {
    position: relative;
    display: inline-block;
    width: 100px; /* 너비 조정 */
    height: 52px; /* 높이 조정 */
}

.toggle-switch .checkbox {
    opacity: 0;
    width: 0;
    height: 0;
}

.toggle-switch .label {
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: var(--toggle-background-light);
    transition: background-color 0.4s;
    border-radius: 52px; /* 둥근 모서리 반경 조정 */
}

.toggle-switch .label:before {
    position: absolute;
    content: "";
    height: 48px; /* 내부 원 높이 조정 */
    width: 48px; /* 내부 원 너비 조정 */
    left: 2px;
    bottom: 2px;
    background-color: var(--toggle-ball-light);
    transition: transform 0.4s;
    border-radius: 50%;
}

.toggle-switch input:checked + .label {
    background-color: var(--toggle-background-dark);
}

.toggle-switch input:checked + .label:before {
    transform: translateX(48px); /* 내부 원 이동 거리 조정 */
}

.content {
    text-align: center;
    transition: color 0.3s;
}

/* Optional: Font Awesome Icons */
.fas.fa-sun, .fas.fa-moon {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    transition: color 0.3s, opacity 0.3s;
}
/* 아이콘 크기 조정을 위한 클래스 추가 (선택적) */
.fas {
    font-size: 24px; /* 아이콘의 폰트 크기 조정 */
}
.fa-sun {
    color: #f1c40f;
    left: 8px; /* 위치 조정 */
    opacity: 1; /* 기본 가시성 */
}

.fa-moon {
    color: #f39c12;
    right: 8px; /* 위치 조정 */
    opacity: 0; /* 기본 가시성 */
}

.toggle-switch input:checked ~ .fa-sun {
    opacity: 0; /* 다크 모드에서 해 아이콘 숨김 */
}

.toggle-switch input:checked ~ .fa-moon {
    opacity: 1; /* 다크 모드에서 달 아이콘 표시 */
}

 

 

 


 

다크모드 토글 JAVASCRIPT 작성 - js / script.js 작성하기

 

javascript 출처

 

JavaScript를 사용하여 다크모드 토글 기능을 구현합니다. 사용자의 다크모드 선호를 로컬 스토리지에 저장하여, 페이지를 재방문할 때 이전 설정을 유지하도록 합니다.

이 예제를 완성 후 다크모드 토글을 사용한 뒤에 새로고침을 눌러보세요!

 

document.addEventListener('DOMContentLoaded', function() {
    const darkModeToggle = document.getElementById('darkModeToggle'); // 토글 버튼 선택
    const moonIcon = document.querySelector('.fa-moon'); // 달 아이콘 선택
    const sunIcon = document.querySelector('.fa-sun'); // 해 아이콘 선택

    // 로컬 스토리지에서 다크 모드 설정을 불러와 적용하는 함수
    function applyInitialTheme() {
        const isDarkMode = localStorage.getItem('darkMode') === 'true';
        document.body.classList.toggle('dark-mode', isDarkMode);
        darkModeToggle.checked = isDarkMode;
        // 다크 모드 상태에 따라 아이콘의 opacity 조정
        moonIcon.style.opacity = isDarkMode ? "1" : "0";
        sunIcon.style.opacity = isDarkMode ? "0" : "1";
    }

    // 다크 모드 상태를 토글하고 로컬 스토리지에 저장하는 함수
    function toggleDarkMode() {
        const isDarkMode = document.body.classList.toggle('dark-mode');
        localStorage.setItem('darkMode', isDarkMode);
        // 다크 모드가 활성화되면 달 아이콘을 보이게, 해 아이콘을 숨김
        moonIcon.style.opacity = isDarkMode ? "1" : "0";
        sunIcon.style.opacity = isDarkMode ? "0" : "1";
    }

    // 페이지 로드 시 초기 다크 모드 설정 적용
    applyInitialTheme();

    // 토글 버튼에 클릭 이벤트 리스너 추가
    darkModeToggle.addEventListener('change', toggleDarkMode);
});

 

다음은 코드 설명입니다.

 

document.addEventListener("DOMContentLoaded", function() {
} # DOMContentLoaded 이벤트 리스너

 

  • 이 스크립트는 웹 페이지의 DOM 구조가 완전히 로드되고 준비된 후에 실행됩니다. DOMContentLoaded 이벤트가 발생하면, 주어진 함수가 호출됩니다.

 

const darkModeToggle = document.getElementById('darkModeToggle'); // 토글 버튼 선택
const moonIcon = document.querySelector('.fa-moon'); // 달 아이콘 선택
const sunIcon = document.querySelector('.fa-sun'); // 해 아이콘 선택

 

  • darkModeToggle: 다크 모드를 토글하는 체크박스 입력 요소입니다.
  • moonIcon과 sunIcon: 다크 모드와 라이트 모드를 나타내는 아이콘으로, 다크 모드 상태에 따라 가시성이 변경됩니다.

 

// 로컬 스토리지에서 다크 모드 설정을 불러와 적용하는 함수
    function applyInitialTheme() {
        const isDarkMode = localStorage.getItem('darkMode') === 'true';
        document.body.classList.toggle('dark-mode', isDarkMode);
        darkModeToggle.checked = isDarkMode;
        // 다크 모드 상태에 따라 아이콘의 opacity 조정
        moonIcon.style.opacity = isDarkMode ? "1" : "0";
        sunIcon.style.opacity = isDarkMode ? "0" : "1";
    }

 

  • 페이지 로드 시 호출되어, 로컬 스토리지에서 darkMode의 저장된 값을 불러옵니다.
  • isDarkMode 변수를 통해 다크 모드 상태를 확인하고, 이에 따라 body 태그에 dark-mode 클래스의 추가 또는 제거, 토글 버튼의 체크 상태, 그리고 달과 해 아이콘의 opacity를 조정합니다.

 

 

// 다크 모드 상태를 토글하고 로컬 스토리지에 저장하는 함수
function toggleDarkMode() {
    const isDarkMode = document.body.classList.toggle('dark-mode');
    localStorage.setItem('darkMode', isDarkMode);
    // 다크 모드가 활성화되면 달 아이콘을 보이게, 해 아이콘을 숨김
    moonIcon.style.opacity = isDarkMode ? "1" : "0";
    sunIcon.style.opacity = isDarkMode ? "0" : "1";
}

 

 

  • 토글 버튼의 상태 변경(change 이벤트) 시 호출됩니다.
  • document.body.classList.toggle('dark-mode')를 사용하여 dark-mode 클래스를 body 태그에 추가하거나 제거합니다. 이는 다크 모드와 라이트 모드를 전환합니다.
  • 로컬 스토리지에 현재 다크 모드 상태(isDarkMode)를 저장합니다.
  • 다크 모드가 활성화되면 달 아이콘의 opacity를 1로, 해 아이콘을 0으로 설정하여 달 아이콘이 보이고 해 아이콘이 숨겨지도록 합니다. 반대 상황에서는 반대로 적용됩니다.

 

 // 토글 버튼에 클릭 이벤트 리스너 추가
    darkModeToggle.addEventListener('change', toggleDarkMode);

 

  • darkModeToggle 요소에 change 이벤트 리스너를 추가하여, 사용자가 토글 버튼을 클릭할 때마다 toggleDarkMode 함수가 호출되도록 합니다.

 

마무리

 

이번 포스팅에서는 모바일 환경을 위한 다크모드 토글 만들기 를 예제를 통해 구현해 보았습니다. 모바일 사용자 경험을 개선하기 위한 다크모드 토글 구현은 사용자의 눈 건강을 보호하고, 앱이나 웹사이트의 접근성을 높이는 효과적인 방법입니다. 이번 포스팅에서는 HTML, CSS, JavaScript를 사용하여 간단하게 구현해보았으며, 사용자로 하여금 더 나은 브라우징 환경을 제공합니다.

해당 코드는 예제 이므로  여러분의 필요에 따라 코드를 조정하고, 자신의 프로젝트에 맞게 커스터마이징 하여 사용할 수 있습니다.

 

다음 포스팅에서도 모바일 환경을 위한 다양한 효과를 만드는 작업을 해보도록 하겠습니다.

 

 

 

 

 

반응형