컬러 팔레트, 테스트부터 시작하는 다크모드 제작 방법
다크모드는 2020년을 대표하는 웹 UI 트랜드입니다. MacOS의 경우 자동으로 탭의 색상, 배경화면까지 시간에 따라 바뀌는 것을 적용한지 오래고, iOS에서는 완벽하진 않지만 다크모드를 지원하기도 합니다. 그 뿐 아니라 많은 서비스에서 직접 다크모드를 제공하고 있습니다.
제가 지난 주에 만든 사이트에도 간단하게나마 다크모드를 적용해봤는데요, 이번 글에선 어떤식으로 다크모드를 Vue 프로젝트에 만들 수 있는지 설명하겠습니다.(제 경우에는 Vuetify와 같은 UI 라이브러리를 사용하지 않았을 뿐 아니라 dark-mode와 같은 모듈을 사용하지 않았습니다. 해당 내용은 글의 중반 이후를 참조해주세요.)
다크모드를 만들기 위해서는 많은 방법이 있지만 가장 선행되는 작업이 있습니다. 바로 컬러 팔레트입니다.
웹디자이너가 디자인한 웹서비스의 경우 대부분 컬러팔레트가 존재합니다. 각 기능의 색상이 구분되어있고, 공유하는 스타일 세트가 존재합니다. 다크모드에서는 이미 설정한 컬러팔레트를 바탕으로 대칭점을 만드는 컬러세트가 필요하며, 이를 바탕으로 다크모드를 완성할 수 있습니다.
디자인을 그때그때 한 서비스에는 제대로 된 색상 구성이 이뤄져있지 않을 수 있습니다. 다른말로는 디자인 시스템이 정립되어있지 않다고 할 수 있죠. 다행히도 컬러팔레트는 다크모드의 필수 선행조건이지만 몇가지 방법으로 과정을 단축시킬 수 있습니다.
컬러팔레트가 없는 Vue 프로젝트에 다크모드를 적용하려면 먼저 색상을 그룹화해야합니다. 그룹화는 유사한 색상을 최대한 묶음으로 처리해 하나의 변수에 할당하는 일입니다. 이 과정에서 색상값을 통일하기도 합니다. 방법은 다음과 같습니다.
- 스타일시트의 color, background-color, border-color, shadow color 등 색상 관련 값만 정리합니다.
- 필요하다면 유사한 컬러를 통합합니다.
- 통합된 컬러에 CSS 변수를 할당합니다. (:root에 --color-example과 같은 형태로 설정)
- 사이트에 통합된 컬러가 잘 어울리는지 확인하면서 변수를 늘리거나 줄입니다.
이미 색상이 정해진 상태라면 색상에 대해 변수를 할당하면 됩니다. 이미 변수도 할당된 상태라면 다음으로 진행합니다.
다크모드를 위한 색상을 만들기에 앞서 사이트의 다크모드를 미리 테스트해봅시다.
다크리더와 같은 확장 프로그램을 설치해 사용합니다. 이 단계에서 여러 다크모드 확장 프로그램을 설치해 사용해보시는걸 추천드립니다. 이유는 각각의 확장프로그램이 여러 종류의 다크모드 스타일 및 값 조정을 시도해볼 수 있기 때문입니다.
소개한 다크리더의 경우 밝기와 대비, 세피아와 흑백 필터를 통해서 여러 분위기의 다크모드를 테스트해볼 수 있습니다. 이 과정을 통해서 자신이 원하는 스타일을 찾아봅시다.
위에서 다크모드를 맛봤고, 적당한 배경톤과 폰트 톤을 발견했을 겁니다. 하지만 테마 컬러(theme color)의 경우 제대로 반영되지 못하곤 합니다.
제가 만든 사이트에서는 블루가 테마컬러이고, 다크모드에서는 오렌지를 택했습니다. 제가 오렌지를 택한 이유는 잘 어울리는 이유도 있지만 블루는 다크모드에서 줄여야할 색상으로 보기 때문도 큽니다. 보통 블루라이트는 눈에 피로감을 주므로 블루는 옐로, 오렌지 색으로 치환합니다.
그렇기에 확장프로그램은 채도가 높은 색상의 전환은 어색하기도 합니다. 그렇기에 테마 컬러나 테마에 준하는 컬러톤의 경우 다크모드에 대응하는 컬러를 직접 설정해주는 과정이 필요합니다. 이 과정에서 색상 선택이 어렵다면 다크모드용 컬러팔레트를 검색해보시거나, 위에서 공유한 컬러팔레트 사이트를 통해서 색상별 어울리는 색상 조합을 참조해 대칭 컬러를 테스트해볼 수 있습니다.
이제 테마를 적용해봅시다. Vuetify와 같은 라이브러리를 이미 사용하신다면 가이드가 존재하므로 적용 방법은 각 라이브러리를 참조하시면 됩니다. 마찬가지로 기타 모듈 등을 사용하신다면 테마를 적용하는 건 가이드를 따라 진행하시면 됩니다. 그런데 라이브러리가 제대로 작동하지 않거나, 자신이 원하는 방식으로 동작하지 않는다면 제 방법을 따라보시는 것도 좋습니다.
일단 쿠키를 추가합시다. 제 경우에는 theme이라는 쿠키를 생성해 다크모드의 상태를 auto, dark, light로 구분해 저장합니다. auto의 경우 현재 시간에 따라 다크모드를 줍니다. 많은 사이트에서 default값으로 auto(또는 system이라는 이름으로 설정됨) 다크모드를 적용합니다.
최상단 <HTML> 또는 <BODY>에 쿠키값과 연결된 클래스를 추가합니다. 가령 쿠키에서 "dark"라는 값을 받았다면 <HTML class="dark-theme">과 같은 형태입니다. 클래스를 반응형으로 넣는 방법은 Vue 프로젝트마다 조금씩 다를 수 있습니다. 일반적인 Vue 프로젝트는 App.vue에서 computed나 watch를 통해 쿠키값을 변수로 가져와 감시하면 됩니다.
Nuxt의 경우Layout에서 쿠키를 가져오는 걸 추천하고 싶습니다. Store나 plugins에 두고 관리하는 방법도 있습니다만 store의 경우 쿠키를 로드하는 과정에서 원하는 빌드 단계와 다른 단계에 클래스 추가 명령이 발생할 수 있습니다. 태그에 클래스를 추가하려면 해당 vue 파일에서 created 단계 또는 mounted 이후 시점에 일반적으로 로드하면 작동합니다. 하지만 created 이전에 store에 저장한 요청이 발생한다면 해당 요청은 영향을 못 주고 사라지는 경우가 생깁니다.
위에서 :root 항목에 색상 변수를 할당했습니다. 제 경우에는 아래와 같이 선언했습니다.
최상단 태그에 다크모드 상태별 테마가 들어가야하므로 클래스에 따른 변수를 추가해줍니다.
저는 주간 모드에만 추가로 값을 선언하는 형태로 진행했습니다. 이렇게 값을 설정해주면 해당 값은 다크모드에 반응하는 클래스에 따라 변수가 바뀌게 됩니다.
이렇게 변수를 설정하면 다크모드 기능 추가는 모두 마무리됩니다. 엄밀히 말하면 이미 컬러 변수를 잘 구성한 프로젝트의 경우 다크모드는 디자이너에게 값을 받아오는 것만 하면 될 정도로 가볍게 진행될 수도 있습니다. 반면 색상 변수가 정립되어있지않고, 색을 너무 많이 사용하고 복잡하다면 다크모드는 무척 힘든 일이 될겁니다.
그렇기에 Vue 프로젝트를 시작하시려는 초보 개발자 분들의 경우 되도록 Vuetify와 같은 UI 라이브러리를 활용해 디자인 고민없이 쉽게 진행하는걸 추천드립니다. 또한 색상을 설정해야하는 경우 되도록 변수처리를 해서 전역 통합 관리하는 습관을 들여야 프로젝트 완성도에 큰 도움이 됩니다.
마지막으로 다크모드 관리를 위한 레포지토리들이 많이 있습니다.
각각의 레포지토리에는 장단점이 있는데, 자신에게 맞는 디자인 시스템인지 확인하시는걸 우선해서 진행하는 게 좋을 것 같습니다. 아쉽게도 Nuxt와는 호환하지 못하는 케이스도 많다보니 완벽한 라이브러리를 찾아서 해결한다는건 힘든 일입니다. 저도 많은 라이브러리를 적용하려고 시도했으나 마음에 들지 않거나 라이브러리의 미흡한 부분이 많았습니다. 이런 이유에서 직접 다크모드를 구현하시는 게 나을 수도 있다고 조심스럽게 권합니다.