본문 바로가기
블로그 꾸미기

블로그 다크 모드를 만들다.

by 12th_moon 2020. 10. 16.

 

 

 

티스토리 스킨 편집에 한창 재미들린 요즘.

다양한 걸 시도해보고 싶어서 자꾸만 오늘은 어떤걸 바꿔볼까 궁리하는데

그러다 문득 이런 생각이 들었다.

 

 

"지금 스킨에서 다크 모드를 한 번 만들어볼까?"

 

 

다른 스킨으로 바꾸는 것도 좋지만 이번에 바꾼지 얼마 안 됐기 때문에

눈의 피로를 덜어주려는 생각보다는

그냥 새로운 분위기의 스킨을 만들고픈, 두개의 스킨을 같이 쓰고픈 마음이 더 컸다.🤣

 

그런데 하필 이런 생각이 왜 자려고 눕기 전에 들었는지...

얼른 만들어보고 싶어 괜히 핸드폰으로 구글링하면서 두근두근 잠 못 이루다가

다음날 아침에 바로 작업에 착수했다.

 

한 페이지를 다크 모드로 바꾸는 건 자바스크립트, 제이쿼리 쪼렙인 나도 할 수 있지만

페이지가 바뀌어도 한 번 바꾼 모드를 유지해야 하는 부분은 전혀 감을 잡을 수 없어서

이 부분은 오늘도 역시나 구글링으로 해결👍

 

 

 

 

 

 

오늘도 있을 거 다 있는 구글에 how to make dark mode in blog란 키워드로 검색을 하고

 

css-tricks.com/a-complete-guide-to-dark-mode-on-the-web/

 

A Complete Guide to Dark Mode on the Web | CSS-Tricks

“Dark mode” is defined as a color scheme that uses light-colored text and other UI elements on a dark-colored background. Dark mode, dark theme, black mode, night mode… they all refer to and mean the same thing: a mostly-dark interface rather than a

css-tricks.com

이 글을 참고해서 만들었다.

 

설명이 어찌나 친절한지...!

 

다크 모드를 만드는 방법이 매우 상세할 뿐만 아니라,

다크 모드가 단순히 전체적인 색만 어둡게 만드는게 아닌

예시를 하나하나 들어가면서 배경색과 컨텐츠 배경색의 관계라든지,

그림자라든지, 이미지도 같이 어둡게 만들어주는 부분이라든지...

'다크 모드 만들기의 정석'같은 느낌으로 기술 & 디자인적 요소를 함께 설명하고 있다.

 

제목 그대로 다크 모드를 만드는 완벽한 가이드다👍

 

 

 

 

 


 

 

 

 

 

 

https://css-tricks.com/a-complete-guide-to-dark-mode-on-the-web/

 

 

우선 이 친절한 가이드에 따르면 블로그에 다크 모드를 적용하는 방법은 두 가지가 있었다.

- 사용자가 버튼을 클릭해서 다크 모드 on/off 하는 방법

- Windows or Mac OS의 설정을 받아와서 적용하는 방법

 

후자가 조금 더 신기하게 와닿긴 하지만 난 그때그때 내가 조작하는게 더 좋을 것 같아서

처음 생각대로 사용자가 on/off를 조절하는 첫번째 방식을 선택했다.

 

(이 가이드를 발견하기 전에 봤던 게시글 두어개에서는 다 두번째 방법의 설명만 있었다.)

 

 

https://css-tricks.com/a-complete-guide-to-dark-mode-on-the-web/

 

 

 

그리고 다음으로 내가 제일 궁금했던 부분!

페이지가 바뀌어도 현재 설정을 어떻게 유지하느냐 하는 부분인데

이 페이지에서는 두 가지 방식으로 설명해주고 있다.

 

처음에는 오른쪽 방식으로 시도해보고자 했지만 PHP 알못이라(심지어 PHP는 생긴 것도 오늘 처음 봤다.)

그냥 무작정 코드를 복사 & 붙여넣기하며 따라하기엔 아무래도 한계가 있었다ㅜ

 

오른쪽 그대로 코드를 입력해주고 버튼을 클릭하면 body에 dark-theme이란 class가 생겨야 하는데

아무리 버튼을 눌러도 감감무소식에 스타일시트를 찾을 수 없다는 오류 메시지만 뜬다.

 

결국 쿠키를 사용하는 방식은 포기하고 왼쪽의 localStorage를 사용하는 방식을 택했다.

 

 

 

다시 처음부터 차근차근-

thtml문서에 우선 다크 모드를 on/off 할 버튼을 만들어주고, 자바스크립트 코드도 복사 & 붙여넣기로 넣어주고

CSS문서에는 다크 모드에 적용할 스타일을 하나하나 입혀줬다.

 

처음에 멋모를땐 스타일을 수정하는 부분에서 꽤 시간을 잡아먹을 줄 알았는데

스타일을 적용하는 데에는 생각보다 많은 시간이 필요하진 않았다.

 

CSS가 생각보다 수월하게 잘 풀리나 싶었는데 다시 맞닥뜨린 문제 세 개.

 

1. 참고하던 사이트에서 그대로 가져온 스크립트 코드 중 addEventListener에서 오류가 발생

2. 다크 모드를 적용한 상태에서 페이지를 전환하면 다크 모드가 로딩되기 전 라이트 모드가 잠깐 나타났다 사라지는 것.

3. 하나의 버튼으로 다크 모드일 때 light로, 라이트 모드일 때 dark로 텍스트 표시하기

 

 

 

우선 1번 문제는 오류 문구 그대로 addeventlistener cannot read property로 구글링해서 해결!

 

stackoverflow.com/questions/26107125/cannot-read-property-addeventlistener-of-null

 

Cannot read property 'addEventListener' of null

I have to use vanilla JavaScript for a project. I have a few functions, one of which is a button that opens a menu. It works on pages where the target id exists, but causes an error on pages wher...

stackoverflow.com

 

 

 

 

 

알고보니 난 <head>안에 <script>를 넣었더니 문제가 생긴 케이스였는데

그럴 땐 첫번째처럼 코드를 추가해서 그 사이에 코드를 넣어주거나

<head>안이 아닌, <body>에 <script>를 배치하면 된다고 한다.

 

간단하게 두 번째 방법으로 해결~

 

 

 

그리고 다시 문제ㅠㅠ

 

 

 

꼼꼼히 정독하지 않아서 내가 지나친 부분이 있었는데

내가 맞닥뜨린 문제 중 2번은 친절한 튜토리얼 페이지에도 언급되어 있었다.

굵은 글씨로 "flash of incorrenct theme"(FOIT)라고 설명했던 게 바로 이런 부분이었던 듯.

 

어두운 화면이 전환되는 가운데 밝은 화면이 잠깐 나왔다 사라지는 것이 보기에도 별로지만

기술적으로도 결함이라 우선 이 부분을 먼저 해결하고 싶었다.

 

 

로딩하는 찰나를 로딩페이지로 가려볼까 싶어서 급하게 로딩페이지를 넣어봤지만

이런걸로 가려질리가 만무, 눈가리고 아웅 작전은 실패 ㅠ

 

결국 혼자 몇 시간을 끙끙대며 이리저리 고민하다가

제이쿼리를 따로 추가하면서 1, 2번 문제를 동시에 해결했다.

 

<script>
  $(window).load(function(){
    if($('body').hasClass('dark-theme')){
    	$('.btn-toggle').toggleClass('btn-light').html('<span>light</span>');
    }else{
      $('.btn-toggle').toggleClass('btn-dark').html('<span>dark</span>');
      $('body').toggleClass('light-theme');
    }
    $('.btn-toggle').on('click', function(){
      if($('body').hasClass('dark-theme')){
        //dark-mode
        $('.btn-toggle').removeClass('btn-dark').html('<span>dark</span>');
        $('.btn-toggle').addClass('btn-light').html('<span>light</span>');
        $('body').removeClass('light-theme');
        $('body').addClass('dark-theme');
      }else{
        //light-mode
        $('.btn-toggle').removeClass('btn-light').html('<span>light</span>');
        $('.btn-toggle').addClass('btn-dark').html('<span>dark</span>');
        $('body').removeClass('dark-theme');
        $('body').addClass('light-theme');
      }
    });
  });
</script>

 

제이쿼리도 쪼렙이라 뭔가 코드도 더러워 보이고...

해결해 놓고도 여전히 이게 맞나 싶지만,

어쨌든 이 코드로 2, 3번 문제를 함께 해결하긴 했다.

 

처음에 난 라이트 모드의 배경화면을 스타일시트에서 그냥 body에 적용하고,

다크 모드일 땐 body에 dark-theme이란 class가 생겨서 .dark-theme으로 적용했었는데

라이트 모드일때에도 body에 light-theme이란 class를 만들어서

그냥 body가 아닌, .light-theme에 배경화면을 적용했다.

그랬더니 일단 가장 문제였던 모드 전환 중 깜빡임 현상은 해결!

(깜빡임 현상을 해결하고 나니 로딩페이지를 지울까 했지만 디자인이 나름 마음에 들어서 로딩페이지도 그냥 그래도 두었다.)

 

 

 

그리고 이어서 body에 각각의 모드에 맞는 class가 생기니

처음 페이지가 로드될 때 버튼의 텍스트를 표시하기도,

클릭해서 모드가 바뀌었을 때 버튼의 텍스트를 바꾸기도 용이했다.

 

처음 라이트 모드의 body에 class가 따로 없었을 땐 버튼의 light / dark 텍스트를 조절하기 힘들었다ㅜ

html에는 애초에 light나 dark의 텍스트를 하나도 넣어두지않고(<a href="#" class="btn-toggle"></a>)

만약 다크 모드에서 페이지가 로드 됐으면 처음엔 light 버튼이었다가 클릭하면 다시 dark로 바뀌고,

또 라이트 모드에서 페이지가 로드 됐다면 dark버튼이었다가 클릭하면 다시 light로 바뀌게 만드는 게 목표였다.

 

이 부분은 완벽한 가이드에도 버튼 디자인에 대한 설명은 없어서 혼자 머리 싸매고 끙끙대긴 했지만

addClass, removeClass 실컷 써가면서 해결하고 보니 이렇게 간단한걸 왜 계속 붙들고 있었나 싶다.

 

 

버튼 하나로 전환하는 다크 모드 완성!

 

 

 

 

마지막으로 다크 모드를 만든 기념으로 기쁨의 화면녹화!

 

 

끝났다고 신나했더니 다크 모드와 라이트 모드의 전환 속도가 왜 다르지...?

 

 

 

 


 

 

 

 

어찌됐든 일단 끝냈다는 생각에 크롬 개발자도구의 Lighthouse로 리포트를 생성해보니 퍼포먼스 점수가 영 형편없게 나온다.

 

시간을 많이 잡아먹는 것 중 하나가 바로 제이쿼리였는데

티스토리 자체에서 가져오는 제이쿼리가 3.2.1버전의 라이브러리라면 내가 또 링크를 건 것이 1.12.4버전의 라이브러리ㅠ

 

 

 

 

그래서 위에 제이쿼리로 썼던 부분을 싹 자바스크립트로 바꿔서

가이드에서 가져온 자바스크립트 코드에 싹 다 끼워넣었다.

(버튼의 텍스트를 바꾸는 방법은 생각해보니 CSS로도 충분히 가능해서 그건 CSS로 대체)

 

그리고 속도가 좀 더 향상되면 그때 살리기로 하고 로딩페이지도 삭제~

 

아직 제이쿼리 전부를 자바스크립트로 바꾼 게 아니라서 1.12.4 라이브러리를 지우진 못했지만

그래도 이렇게나마 바꾸니 속도도 체감상 약~간 빨라진 것 같고

두 모드가 전환될 때의 속도도 같아졌다.

 

스크립트랑 CSS를 두서없이 바꾸느라 아직 엉망진창이지만

첫술에 배부를 순 없기 때문에 앞으로 계속해서 이리저리 만져봐야겠다.

 

 

 

 

 

 

 

 

 

 

댓글