본문 바로가기
프로젝트/OpenEDC

[OpenEDC] 다크모드 지원

by Whiimsy 2022. 5. 31.

저번엔 한국어를 추가했었고, 이번엔 다크 모드를 추가해보도록 하자! 야매긴 하지만..

한국어 추가했던 포스트

 

🧀 팔레트 만들기

css 폴더에 palette 폴더를 만들어 기본으로 사용할 색상들을 담을 baisc.css 파일과 다크 모드로 변경 시 사용할 색상들을 담을 dark.css 파일을 만든다. 주 사용 css인 lib/bulma.css 파일을 보고 다크 모드로 토글 했을 때 바뀔 색상들을 뽑아 basic.css를 만들어 보자!

/* css/basic.css */
:root {
  --background: #ffffff; /* 전체 배경 */
  --font: #363636; /* 기본 폰트 */

  --warn-back: #feecf0; /* 경고 컨테이너 배경 */

  --button-back: #eef3fc; /* 버튼 배경 */
  --button-font: #2160c4; /* 버튼 폰트 */
  --button-hover: #e3ecfa; /* 버튼 호버 배경 */
  --button2-hover: #eeeeee; /* 버튼 호버 배경2 */

  --menu-hover: #fafafa; /* 메뉴 호버 배경 */

  --sidebar-active: #d8e4f8; /* 사이드바 활성화 배경 */

  /* grayscale */
  --gray-100: #f9f9f9;
  --gray-200: #f5f5f5;
  --gray-300: #f2f2f2;
  --gray-400: #ededed;
  --gray-500: #e8e8e8;
  --gray-600: #dbdbdb;
  --gray-700: #d6d6d6;
  --gray-800: #b5b5b5;
  --gray-900: #4a4a4a;
  
  --shadow: rgba(10, 10, 10, .1); /* 그림자 */

  --dark: rgba(0, 0, 0, 0.7); /* 검은색 */
  --deep-dark: #0a0a0a; /* 검은색2 */
}

 

basic.css에 정의된 색상들을 다크 모드로 토글 했을 때 어떤 색상으로 변경하고 싶은지 dark.css에 정의해준다.

/* css/dark.css */
:root {
  --background: #363636; /* 전체 배경 */
  --font: #ffffff; /* 기본 폰트 */

  --warn-back: #d6c6c8; /* 경고 컨테이너 배경 */

  --button-back: #323232; /* 버튼 배경 */
  --button-font: #488eff; /* 버튼 폰트 */
  --button-hover: #303030; /* 버튼 호버 배경 */
  --button2-hover: #444444; /* 버튼 호버 배경2 */

  --menu-hover: #303030; /* 메뉴 호버 배경 */

  --sidebar-active: #27292b; /* 사이드바 활성화 배경 */

  /* grayscale */
  --gray-100: #303030;
  --gray-200: #404040;
  --gray-300: #4a4a4a;
  --gray-400: #4a4a4a;
  --gray-500: #e8e8e8;
  --gray-600: #ededed;
  --gray-700: rgba(10, 10, 10, .4);
  --gray-800: #f5f5f5;
  --gray-900: #f9f9f9;
  
  --shadow: rgba(10, 10, 10, .4); /* 그림자 */

  --dark: rgba(255, 255, 255, 0.7); /* 흰색 (basic에서 검은색이었으니까 변수명은 --dark) */
  --deep-dark: #e8e8e8; /* 흰색2 */
}

 

🧀 팔레트 적용하기

팔레트의 색상 변수들(ex. --background)을 style.css와 bulma.css에 적용해준다!

요런 식으로 정의된 색상 코드를 찾아 변수명으로 바꿔 주도록 하자.

바꿔준 후 index.html 파일에 아래 코드를 추가하면 팔레트 색상이 정상적으로 작동할 것이다! id를 이용해 css 파일의 경로를 바꿔주는 것으로 테마를 토글 할 것이기 때문에 id를 theme로 지정해준다.

<!-- index.html -->
<link rel="stylesheet" id="theme" href="./css/palette/basic.css" />

 

🧀 다크 모드 토글 추가하기

코드펜에서 마음에 드는 다크 모드 토글을 골라 네비게이션 바의 원하는 위치에 추가해준다.

<!-- index.html 다크 모드 토글에 사용할 아이콘 스크립트 추가 -->
<script src="https://code.iconify.design/1/1.0.4/iconify.min.js"></script>

 

<!-- js/components/navigationbar.js -->
<div class="navbar-item">
    <label>
        <input class='toggle-checkbox' type='checkbox'></input>
        <div class='toggle-slot'>
            <div class='sun-icon-wrapper'>
                <div class="iconify sun-icon" data-icon="feather-sun" data-inline="false"></div>
            </div>
            <div class='toggle-button'></div>
            <div class='moon-icon-wrapper'>
                <div class="iconify moon-icon" data-icon="feather-moon" data-inline="false"></div>
            </div>
        </div>
    </label>
</div>

 

원하는 대로 css를 수정해준다.

/* css/style.css */
.toggle-checkbox {
  position: absolute;
  opacity: 0;
  cursor: pointer;
  height: 0;
  width: 0;
}

.toggle-slot {
  position: relative;
  height: 2.5rem;
  width: 5rem;
  border: 2px solid var(--gray-500);
  border-radius: 1.5rem;
  background-color: white;
  transition: background-color 250ms;
  cursor: pointer;
}

.toggle-checkbox:checked ~ .toggle-slot {
  background-color: #363636;
}

.toggle-button {
  transform: translate(2.8rem, 0.3rem);
  position: absolute;
  height: 1.625rem;
  width: 1.625rem;
  border-radius: 50%;
  background-color: #ffeccf;
  box-shadow: inset 0px 0px 0px 0.1875rem #ffbb52;
  transition: background-color 250ms, border-color 250ms,
    transform 500ms cubic-bezier(0.26, 2, 0.46, 0.71);
}

.toggle-checkbox:checked ~ .toggle-slot .toggle-button {
  background-color: #363636;
  box-shadow: inset 0px 0px 0px 0.1875rem var(--white);
  transform: translate(0.4rem, 0.3rem);
  border: 2px solid #fff;
}

.sun-icon {
  position: absolute;
  height: 1.5rem;
  width: 1.5rem;
  color: #ffbb52;
}

.sun-icon-wrapper {
  position: absolute;
  height: 1.5rem;
  width: 1.5rem;
  opacity: 1;
  transform: translate(0.5rem, 0.38rem) rotate(15deg);
  transform-origin: 50% 50%;
  transition: opacity 150ms, transform 500ms cubic-bezier(0.26, 2, 0.46, 0.71);
}

.toggle-checkbox:checked ~ .toggle-slot .sun-icon-wrapper {
  opacity: 0;
  transform: translate(0.75rem, 0.5rem) rotate(0deg);
}

.moon-icon {
  position: absolute;
  height: 1.5rem;
  width: 1.5rem;
  color: white;
}

.moon-icon-wrapper {
  position: absolute;
  height: 1.5rem;
  width: 1.5rem;
  opacity: 0;
  transform: translate(2.5rem, 0.5rem) rotate(0deg);
  transform-origin: 50% 50%;
  transition: opacity 150ms, transform 500ms cubic-bezier(0.26, 2.5, 0.46, 0.71);
}

.toggle-checkbox:checked ~ .toggle-slot .moon-icon-wrapper {
  opacity: 1;
  transform: translate(3rem, 0.38rem) rotate(-15deg);
}

 

🧀 다크 모드 토글 함수 구현하기

테마를 토글 할 버튼을 만들었으므로 이제 버튼을 눌렀을 때 테마가 토글 되게 하는 함수를 구현해보자! 아까 지정한 id를 받아와 css 경로(href 값)를 바꾸어준다. 또 새로고침 했을 때 다크 모드가 풀리지 않고 유지되게 하기 위해 로컬 스토리지를 사용해준다.

// js/app.js
window.handleTheme = function () {
  var tm = document.getElementById("theme");
  if (tm) {
    var arr = tm.href.split("/");
    if (arr[arr.length - 1] == "basic.css") {
      tm.href = "../css/palette/dark.css";
      localStorage.setItem("theme", "dark");
    } else {
      tm.href = "../css/palette/basic.css";
      localStorage.setItem("theme", "basic");
    }
  }
  reportsModule.reload(); //?
};

 

<!-- index.html body 태그 뒤에 작성!! -->
<script>
  if (localStorage.getItem("theme") == "dark") {
    document.getElementById("theme").href = "../css/palette/dark.css";
    document.getElementById("theme-dark").checked = true;
  }
</script>

 

구현한 함수를 버튼의 onClick 속성에 달아준다.

<!-- js/components/navigationbar.js -->
<div class='toggle-slot' onclick="handleTheme()">

 

🧀 중간 점검

 

 

🐱‍👤 참고 : https://codepen.io/bheberer/pen/BaNZKmq

 

'프로젝트 > OpenEDC' 카테고리의 다른 글

[OpenEDC] 중간 회고회고  (0) 2022.06.20
[OpenEDC] 스킨 커스텀하기 - 2  (0) 2022.06.13
[OpenEDC] 스킨 커스텀하기 - 1  (0) 2022.06.10
[OpenEDC] 한국어 추가하기  (0) 2022.05.27
[OpenEDC] 페이지 분석  (0) 2022.05.25