Dark Mode 적용

by Joongi Kim

오랜만에 블로그를 업데이트하였다. 원래 별다른 게 없던 사이트라 별다른 게 바뀐 건 아니고 macOS Mojave와 Windows 10 이후 유행하기 시작한 dark mode를 적용했다. Safari에서 먼저 도입되어 현재 표준화 과정 중에 있는 prefers-color-scheme CSS media query를 사용했고, 사용자가 별도로 수동 설정할 수 있는 기능은 따로 넣지 않았다. 즉, OS와 브라우저가 해당 CSS 기능을 지원한다면 OS 기본 설정에 따라 자동으로 dark mode가 적용될 것이다. caniuse.com에 따르면 이 기능은 Chrome에서도 구현 중이고 Firefox도 다음 stable release부터 지원 예정이니까 조만간 대부분의 데스크톱 환경에서는 동작하리라 생각된다. (Edge는 Chromium 엔진으로 교체를 준비하고 있으므로 Chrome 구현을 따라갈 가능성이 높다.)

그리고 이번 포스팅은 각별히 더 큰 의미가 있는데, 바로 내 블로그 글 중에 비행기—북태평양 상공—에서 작성해서 업로드한 최초의 글이라는 점이다. (비행기에서 작성하니만큼 dark mode가 특히 더 유용했음은 말할 것도 없다.) 올해 상반기에만 벌써 5번째 해외출장으로 TensorFlow Dev Summit과 NVIDIA GTC에 이어 Google I/O 참석 차 올해 세번째 샌프란시스코 방문하는 길이다. 그동안 어쩌다보니 계속 대한항공을 타다가 오랜만에 아시아나를 타게 되었는데1, 유나이티드항공과 코드쉐어가 되면서 무려 랩탑을 충전할 수 있는 콘센트와 기내 WiFi 서비스(24시간 사용시 $21.95)가 제공되는 A350 기종을 타게 되는 행운(?)을 얻었다.

여튼 그래서 업데이트 내용을 살짝 정리해두고자 한다. 요즘은 React나 Vue.js, 혹은 Polyer/Lite Elements와 같이 웹컴포넌트 기술을 모토로 하는 프론트엔드 기술이 많이 사용되지만, 이 블로그는 클래식하게(...) Bootstrap 4 기반이다. 백엔드는 GitHub Pages를 사용하나 Jekyll 대신 Lektor라는 Python 기반의 static site generator를 이용하고 있다. 대충 한 일은 다음과 같다:

  • 기존에 어설프게 webpack v1으로 패키징하던 부분(브라우저의 자바스크립트 콘솔을 보면 뭔가 로딩이 안 돼서 에러도 막 뜨던...)을 엎어쳐서 webpack v4에 맞게 대응시켰는데, 이게 또 Bootstrap이 v4로 올라올 때 UMD를 걷어내면서 별도의 bootstrap-loader 패키지와 별도의 수동 plugin 객체 매핑이 필요하였다. (기존에는 이 부분이 아예 깨져있어서 Bootstrap의 자바스크립트 부분은 제대로 로딩조차 안되고 있었음)
  • webpack도 Lektor를 쓰는 바람에 저장소의 최상위 경로가 아닌 별도 하위 디렉토리에서 동작시키다보니 뭔가 node_modules 디렉토리 자동인식(~로 참조 가능)이 안 되는 이슈가 있었다. 삽질하다 포기하고 걍 ../../../webpack/node_modules/를 참조하는 것으로 해결.
  • 처음에는 SCSS 변수로 light/dark mode의 색상값만 다르게 지정하려고 하였으나, CSS 전처리기의 특성 상 그 변수들은 실제 컴파일된 CSS에는 존재하지 않아서 결과적으로 @media 구문 내부가 비어버리는 현상이 발생했다. 최신 CSS variable 규격을 사용한다면 해결할 수 있지만 안타깝게도 Bootstrap v4는 다른 곳에서 사용하라고 SCSS로 컴파일된 결과물로서 색상값들을 CSS variable로 노출시켜주기만 할뿐 자기 자신이 그걸 입력으로 사용하지는 않는다. 결국은 style-light.css와 style-dark.css로 webpack entrypoint를 쪼개서 layout.html 템플릿에서 @import하되 media 조건을 붙이는 식으로 해결.
  • light mode에서는 style-light.css만 불러오지만 dark mode에서는 그걸 불러온 다음 style-dark.css로 덮어쓴다. 내부 색상값만 다르고 다른 부분은 모두 중복되는 스타일시트를 불필요하게 두번씩 로딩하는 셈인데, 이건 위에서 이야기한 대로 SCSS로 색상 모드를 구현하는 한 어쩔 수 없는 부분. 모든 브라우저가 prefers-color-scheme media query를 정식 지원하여 @import 구문을 아예 if-else처럼 분기타게 하거나, Bootstrap에서 native CSS variable을 색상테마 입력값으로 지원해주거나, 또는 Bootstrap을 버리고 직접 짜면 해결할 수 있으나, 트래픽도 얼마 없는 개인 블로그에서 160 KiB 두번 불러온다고 큰일날 것 같지 않아서 일단 두었다.
  • light/dark mode 색상프로필을 직접 만들까 하다가 그것도 다 귀찮아서 bootswatch의 flatly와 darkly 테마를 그대로 import하도록 하였다. $light$dark는 기본으로 정의되는데, 그 중간인 $gray에 해당하는 값은 따로 정의되지 않아서 두 색상프로필에 각각 직접 정의하였다.

자바스크립트 분야는 워낙 변화가 빨라서인지—구글링하면 다 나오기는 하지만—뭔가 최신 버전과 최신 버전을 연동할 때 매뉴얼 대로 한번에 되는 경우가 잘 없다. 뭔가 삽질하면 해결되기는 하는데, 뭔가 항상 hack을 동원해야 하는 느낌이랄까. 기본 tutorial만 보면 참 아름답고 깔끔한데 막상 해보면 절대 그렇게 끝나지 않는다. 이것이 문서화가 약해서인지 아니면 정말 기술 발전이 너무 빨라서 그런 것인지 혹은 백엔드 기술들처럼 안정성이나 호환성보다는 섹시함을 추구해서인지는 잘 모르겠지만, 건드릴 때마다 느끼는 건 프론트엔드 개발하는 사람들은 매일매일 고생하겠구나 싶다.

여튼 생존신고 겸 오랜만의 포스팅 하나 완료.


  1. 대학원에서 학회 출장 갈 때는 주로 아시아나와 스타얼라이언스를 이용하다가 올해 갑자기 대한항공을 많이 이용하게 되면서 양쪽으로 마일리지가 분산되어버렸다. 어어 하다보니 양쪽 마일리지 합치면 아시아권 비즈니스 승급이 가능할 정도가 되었다... ㅠㅠ