본문 바로가기
IT팁

Tistory 다크모드, 어두운 테마 적용하기

by 개발새-발 2022. 7. 7.
반응형

저는 주로 다크테마를 설정해두고 작업을 합니다. 핸드폰, 태블릿, 노트북 모두 다크테마에 어두운 배경화면으로 설정을 하였습니다. 밤에 작업을 하다 밝은 화면이 나와 저의 눈을 부시게 하는것을 막기위함이었습니다.

하루는 작업을 하다 어떤 내용이 가물가물 한겁니다. 생각해보니 예전에 블로그에 써놓은 내용인 것 같아 제 블로그에 접속하였습니다. 아뿔싸, 제 블로그의 배경은 순수 하얀색이었고 접속하는 순간 모니터는 매우 밝아졌습니다. 모니터를 향해있던 두 눈의 동공은 신속히 쭈그러들면서 고통을 안겨주었습니다. 블로그에 어두운 색상구성을 추가해야할 필요성을 느끼게 된 순간이었습니다.

대략적인 방법

사실 시스템 테마값만을 사용하여 어두운 테마의 사용여부를 결정한다면 CSS 에서 미디어 쿼리(Media Query) 만을 사용하여 해결할 수 있습니다. 그러나, 버튼을 사용한 전환과 사용여부를 저장해서 사용하려면 Javascript 를 연결하여 사용하는 것이 편리합니다.

전 CSS 에서 Data attribute 에 따라 적용될 색상의 값을 설정하고 Javascript에서 이 Data attribute 의 값을 조작하여 적용여부를 설정하는 방법으로 진행하였습니다. 이 예제에서 조작될 Data attribute 의 이름은 isBlack 입니다.

CSS 부분

CSS 부분에서는 Custom Property가 사용됩니다. 같은 이름의 Custom Property에 대해 기본 테마에서의 값과 어두운 테마에서의 값을 설정 하고 원하는 부분에서 Custom property 를 사용 합니다. 위 사진에서 노란 색으로 표시된 부분입니다.

Data attribute도 사용됩니다. isBlack 의 값에 따라 적용되는 Custom Property 의 값이 달라지게 할것입니다. 예를 들어 위 사진에서 isBlacktrue 값이 아니라면 기본 테마를 사용하라는 의미입니다. 기본으로 설정된 값이 사용될 것이기 때문에 Custom Property 의 값은 :root 에서 정의한 값을 사용하게 됩니다. 그러나 isBlack 값이 true 값이라면 [data-is-black=true]{...} 부분에서 다시 설정된 Custom Property 을 사용합니다.

JS 부분

Javascript 부분에서는 data attribute 만을 조작합니다. 시스템 값을 불러와서 설정을 하든, 저장된 값을 불러와 설정을 하든, 버튼을 눌러 설정을 하든 Data attribute 값인 isBlack 을 조작하게 하도록 하면 됩니다.

JS 에서 Data Attribute 조작

아래 코드가 삽입될 위치는 head 의 마지막 부분입니다. 단 페이지 로딩이 시작될 때 깜빡거리는 현상이 발생할 수 있습니다. 이경우, document.body.dataset.isBlack = value 내용의 scriptbody 의 맨 첫 부분에 삽입하면 해결됩니다.

<html>
    <head>
    ~~~
    ~~~
        <script>
            여기에 추가!
        </script>
    </head>
    <body>
        <script>
            깜빡거릴 떄 여기에 추가코드!
        </script>
        ~~~~~
        ~~~~~
    </body>
</html>

시스템 어두운 테마 적용 여부 확인하여 조작하기

시스템의 테마 적용 여부를 확인하여 어두운 테마 적용 여부를 결정해 봅시다. 이를 위해 Media query 가 사용됩니다. 아래 값이 true 인지 아닌지만 확인하면 됩니다.

let value = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches

document.body.dataset.isBlack = value

media query 가 지원되고, 어두운 테마가 시스템 설정인 경우 isBlacktrue 가 됩니다.

버튼을 누를때마다 바꾸게 하기

버튼을 누를 때마다 테마 적용 여부가 달라지게 하고 싶을때에도 data attributeisBlack 값만 변경하면 됩니다. value 는 이미 true 혹은 false 중 하나의 값을 가지고 있고 버튼의 클래스는 .blackmodebt 라 가정합시다.

$(document).on("click", ".blackmodebt", function(){
    value = !value;
    document.body.dataset.isBlack = value;
})

저장된 값 사용하기

사용자가 버튼을 눌러 설정한 값을 저장하고 싶을 떄 localStorage 를 사용하여 구현한 코드입니다. 시작할 때 값을 불러오고 버튼을 누를 때 값을 저장합니다. getItem 은 값이 존재하지 않을 때 null 값을 반환하고, 값이 존재한다면 문자열로 반환함으로 이에 유의하여 코드를 작성합니다.

let value = localStorage.getItem("isBlack");

value = (value =='true');

$(document).on("click", ".blackmodebt", function(){
    value = !value;
    localStorage.setItem("isBlack", value);
    document.body.dataset.isBlack = value;
})

시스템 테마 확인, 버튼, 저장된 값 모두 사용하기

위에서 사용한 세가지 방법을 모두 섞어봅시다.

let value = localStorage.getItem("isBlack");
if(value == null){
    value = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
}else{
    value = (value =='true');
}        

$(document).on("click", ".blackmodebt", function(){
    value = !value;
  localStorage.setItem("isBlack", value);
    document.body.dataset.isBlack = value;
})

저장된 값이 먼저 사용되고 저장된 값이 없다면 시스템 테마 값을 사용합니다. 이후 버튼을 눌러 테마를 바꾸는 경우 그 결과는 저장되어 이후에 계속 사용됩니다.

CSS 에 Custom Property 선언 및 적용

색상값의 재사용을 위해 :root 에 Custom Property를 선언하고, #fff 와 같이 바로 값이 적혀있던 부분들을 선언한 Custom Property를 사용하도록 바꾸어 주었습니다. 예를 들어 배경색을 위한 --color-bg 를 선언하고 사용하고자 한다고 가정해 봅시다.

Custom Property 선언

:root 에 Custom Property를 선언하는 방법은 간단합니다. 아래 예제는 --color-bg , --color-000 --color-333 을 선언한 예제입니다.

:root{
    --color-bg : #fff;
    --color-000 : #000;
    --color-333 : #333;
}

위 코드는 기본 테마일때 적용할 색상을 정의한 것입니다. 이제 어두운 테마를 적용하였을 때의 색상을 정의합시다.

[data-is-black=true]{
    --color-bg : rgb(35, 35, 35);
    --color-000 : rgb(228, 228, 228);
    --color-333 : rgb(211, 211, 211);
}

위에 작성한 코드는 data attribute isBlack의 값이 true 일 때 적용되는 코드입니다. 기본 테마에서 배경색상값은 #fff 이고, 어두운 테마에서는 rgb(35,35,35) 가 됩니다. 기본 테마에서 --color-000 의 값은 #000 어두운 테마에서는 rgb(228,228,228) 입니다.

위와 같이 기본 테마에서는 어떤 값이었는데, 어두운 테마에서는 다른 값으로 바꾸고자 하는 값들에 대해 Custom property를 선언을 해 줍니다. 이후 아래의 내용처럼 변화를 원하는 부분에 custom property를 사용해주면 됩니다.

Custom Property 사용

:root 에 선언한 property를 사용해봅시다. 값이 들어갈 위치에 var( --custom-property) 의 꼴로 사용해 주면 됩니다. 예를 들어 아래와 같은 css 구문이 있다고 합시다.

body {
    font-size: 1em;
    line-height: 1.25;
    color: #555;
    background-color: #fff;
}

body 태그에서 background-color 값이 --color-bg 를 사용하도록 바꾸었을때 결과는 아래와 같습니다.

body {
    font-size: 1em;
    line-height: 1.25;
    color: #555;
    background-color: var(--color-bg);
}

이 작업은 어두운 테마를 적용하였을 때 색이 바뀌어야 하는 부분에만 하면 됩니다. 이 작업에 시간이 가장 많이 들었던 것 같습니다. 저는 처음에 #000, #333, #555, #666, #777, #999, … 값들을 모두 --color-000 , --color-333 , … 이름을 가진 custom property로 바꾸어 준 후 이들에 대해 어두운 테마에서 적용될 값을 지정하였습니다. 배경에 대해서도 동일한 작업을 한 후 어색한 부분들만 따로 찾아서 그 부분을 위한 property를 새로 만드는 작업을 반복하였습니다. 어색한 부분들은 브라우저의 개발자 모드로 태그, 클래스 혹은 id 값을 알아내어 CSS 에서 해당 부분을 개별적으로 편집하는 방법으로 진행하였습니다.

적용 결과

이 블로그에선 우측 상단의 달모양 버튼을 누르면 블로그의 테마가 바뀌는 것을 확인할 수 있습니다.

Reference

참고한 사이트입니다.

반응형

댓글