blog update - 다크 테마용 favicon

  • 테마를 전환할 때 favicon url도 업데이트한다
  • 2개의 favicon 파일이 있다
theme.js:44
1
2
3
4
5
6
function setFaviconTheme(theme) {
const href = `https://cdn.jsdelivr.net/gh/chinsun9/chinsun9.github.io@master/img/favicon-bold-color210928${
theme === 'dark' ? '-dark' : ''
}.svg?`;
document.querySelector(`head > link[rel="icon"]`).href = href;
}

메모

  • favicon으로 쓰이는 svg에 어떻게 색을 넘길까..?
  • 그냥 svg 2개 만들어서 토글하기
  • 기존 테마 파일 리팩토링

참고

blog fix 다크 모드 화면 깜박임 제거

화면을 넘어갈 때 눈뽕(기본 테마가 잠깐 렌더링 됨)을 해결하기

상황

  • 다크 모드에서 계속 새로고침하고 있는 상황이다
  • 중간에 번쩍하고 흰색이 보였다
  • 다크 모드 사용 중에 이렇게 새로고침이나 페이지가 넘어갈 때마다 종종 흰색 화면으로 뒤덮이는 문제가 있었다
  • 디폴트 테마 ; 화이트
  • 설정한 테마 ; 다크
  • 다크 모드이면 body에 dark 클래스 추가
  • 다크 모드에서 새로고침이나 화면을 넘어갈 때 잠깐 흰색 화면이 보인다
  • 해결해보자

해결

  • body 태그 바로 아래에 스크립트를 두어 렌더링을 막았다
  • html에 백그라운드 css가 있다면 삭제

알아낸 점

  • 페이지가 넘어갈 때 이전 화면의 백그라운드가 유지된다 (이전 화면의 html이나 body의 백그라운드 컬러)
  • 렌더링은 완전히 파싱이 끝난 후에 이뤄진다
  • 중간에 스크립트를 두어 렌더링을 막을 수 있다(블로킹)
  • color-scheme css를 사용하면 스크롤바 다크 모드도 적용할 수 있다
  • color-scheme css를 사용하면 기본 백그라운드가 생긴다 (dark일시 어두운 백그라운드)

다크 모드 체크리스트

  • color-scheme css 사용하기
  • html 또는 body 태그에 적용되는 백그라운드 색이 있다면 없애기
  • 테마 초기화하는 블로킹 스크립트 넣기

참고

blog update dark theme

  • 캬캬캬
  • 블로그 dark 테마 적용
  • 상단 오른쪽 검색 버튼 옆에서 토글 할 수 있다!!

다크 테마를 적용한 이유

  • github 프로필 메인에 dark theme를 토글하는 버튼이 있었는데
  • 어느샌가 세팅 하위 메뉴로 들어가야 변경이 가능했다
  • 세팅에서 테마를 고르는데 시스템 테마를 상속받아 보여주는 옵션이 있었다
  • 궁금해서 공부해보고 블로그에도 적용하게 되었다
  • 처음 C언어를 배울 때 visual studio 사용했다
  • 기본 테마가 화이트였다
  • 기본 테마를 쓰다가 웹 공부를 시작하면서 유튜버들 세팅을 따라 하다가 다크 테마를 쓰게 됐다
  • 써보니까 괜찮고 좋은 것 같다!

환경

  • 나는 icarus default theme를 사용 중이다

적용 방법

  • 기본적으로 body에 dark class 가 있으면 다크 테마에 맞는 css로 오버라이드하는 방식이다

css 추가

  • dark theme에 맞게 새로 추가할 css는

  • icarus theme 디렉터리를 기준으로 source/css 아래에 dark.styl이름으로 파일을 하나 생성했다
  • 앞으로 나오는 경로는 모두 icarus theme 디렉터리가 기준이다
source/css/dark.styl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
body.dark {
background-color: #1e1e1e;

.navbar {
background-color: #3C3C3C;
color: #d4d4d4;

.navbar-menu {
background-color: transparent !important;

.navbar-item {
color: inherit;

&:hover, &:focus {
background-color: #37373D;
color: #007acc;
}
  • 어떤 테마 시스템이 있고 그런 게 아니라서 하나하나 수작업으로 바꿔주었다
  • body.dark 일 때 css를 오버라이드 할 수 있도록…
source/css/style.styl
1
2
// ...
@import './dark.styl';
  • dark.stylstyle.styl 마지막에 임포트 해준다
  • 그럼 css는 끝!

토글 버튼 추가

  • 이제 토글 버튼을 추가해보자
  • 나는 navbar 상단 오른쪽 검색 버튼 옆에 추가했다
layout/common/navbar.jsx
1
2
3
4
<div class="navbar-end">
<button type="button" id="toggleTheme" class="navbar-item">
hi
</button>
  • layout/common/navbar.jsx 80라인에 toggleTheme라는 ID로 추가했다
  • 이제 버튼에 기능을 넣어줘야 하는데 navbar.jsx에서 기능도 추가하고 싶었는데,
  • 어떻게 빌드되는지 구조를 잘 몰라서 실패했다

  • 대신 source/js 디렉터리에 theme.js 파일을 하나 추가했다
theme.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
const btn = document.getElementById('toggleTheme');

function initTheme() {
// chk local storage
const theme = localStorage.getItem('theme');
if (theme === 'dark') {
document.body.classList.add('dark');
btn.innerText = '🌙';
return;
}
if (theme === 'light') {
btn.innerText = '🌞';
return;
}

// visit first time
const isDark = window.matchMedia('(prefers-color-scheme: dark)');
if (isDark) document.body.classList.add('dark');

localStorage.setItem('theme', isDark ? 'dark' : 'light');
btn.innerText = isDark ? '🌙' : '🌞';
}

function toggleTheme() {
console.log(`toggle theme`);
document.body.classList.toggle('dark');
localStorage.setItem(
'theme',
document.body.classList.contains('dark') ? 'dark' : 'light'
);
btn.innerText = document.body.classList.contains('dark') ? '🌙' : '🌞';
}

window
.matchMedia('(prefers-color-scheme: dark)')
.addEventListener('change', (e) => {
const newColorScheme = e.matches ? 'dark' : 'light';
localStorage.setItem('theme', newColorScheme);

if (newColorScheme === 'dark') {
document.body.classList.add('dark');
btn.innerText = '🌙';
return;
}
document.body.classList.remove('dark');
btn.innerText = '🌞';
});

btn.addEventListener('click', function (event) {
toggleTheme();
});

initTheme();
  • 셀럭터로 위에서 추가한 버튼을 가져와서 클릭 이벤트 리스너를 달아줬다
  • 이제 hexo로 빌드하면서 생성되는 html에 해당 스크립트를 로드하도록 해야 한다

스크립트 파일 추가

  • layout/common/scripts.jsx에 위에서 만든 theme.js를 등록하면 된다
layout/common/scripts.jsx
1
2
3
4
5
<Fragment>
// ...
<script src={url_for('/js/main.js')} defer></script>
<script src={url_for('/js/theme.js')} defer></script>
</Fragment>
  • 56라인 정도 되는 부분에 <script src={url_for('/js/theme.js')} defer></script> 추가한다
  • 마지막으로 hexo 디렉터리로 돌아와서 public/css 하위에 있는 css를 삭제해준다
  • 이제 hexo generate 하게 되면 css가 갱신되고, 테마 토글 버튼이 달려 있는 html이 생성될 것이다

후기

  • 뿌듯하다
  • 다 완성하고 자려고 누워서 폰으로 내 블로그를 들어가 봤는데 눈이 편안했다

web dark theme

  • 깃허브 같은 웹페이지는 내가 다크 모드를 쓰는 걸 어떻게 알고, 자동으로 다크 테마를 지원하는 걸까?

@media (prefers-color-scheme: dark)

  • 미디어 쿼리로 시스템 테마를 읽어 올 수 있다

테마

style.css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
:root {
--top-bar: #dddddd;
--activity-bar: #2c2c2c;
--side-bar: #61616130;
--editor: #ffffff;
--editor-content: #000000;
--status-bar: #007acc;
}

@media (prefers-color-scheme: dark) {
:root {
--top-bar: #3c3c3c;
--activity-bar: #333333;
--side-bar: #252526;
--editor: #1e1e1e;
--editor-content: #ffffff;
--status-bar: #007acc;
}
}
  • 테마는 이런 식으로 정의했다
  • 미디어 쿼리에 걸리면 색상을 정의해둔 사용자 지정 속성들이 오버라이딩된다
  • 색상은 vscode color theme default light, dark에서 가져왔다

테마 토글 버튼

  • 시스템 테마와 별개로 웹페이지에서 테마를 토글 하고 싶을 때는 어떻게 해야 할까?
  • body 태그에 dark라는 클래스를 유무에 따라 테마를 바꿔보자
  • 테마 토글 버튼을 누르면 dark 클래스가 생기고 없어지면서 색상이 적용될 것이다

최초 접속자 테마 초기화

index.js
1
2
3
//   visit first time
const isDark = window.matchMedia('(prefers-color-scheme: dark)');
if (isDark) document.body.classList.add('dark');
  • 미디어 쿼리로는 최초 웹페이지 접속자가 어떤 테마를 사용할지 판단할 때 사용하도록 했다

토글 버튼

index.js
1
2
3
4
5
function toggleTheme() {
console.log(`toggle theme`);
document.body.classList.toggle('dark');
localStorage.setItem('theme', document.body.className ? 'dark' : 'light');
}
  • toggle은 있으면 없애고, 없으면 있게 만든다
  • toggle 후에는 현재 테마 상태를 localStorage에 저장한다
  • 이후 접속 시 localStorage에서 theme에 값이 있는지 확인하고 있으면 해당 테마로 초기화한다

chrome에서 시스템 테마 쉽게 토글 하기

  • f12 개발자 도구에서 esc key 눌러서 하단 console 창을 뛰움
  • three dot (more tools) 눌러서 Rendering 탭 오픈
  • 스크롤 중간 정도에 Emulate CSS media feature prefer-color-scheme 에서 테마 선택

참고

windows dark mode 윈도우 다크 테마

  • 다크 모드는 OS에서 설정할 수 있다
  • 최상위 (OS)에서 설정해두면 그 위에서 돌아가는 앱이 자동으로 테마를 스위치 한다
  • 깃허브 다크 모드가 크롬 프로필에 따라 풀려서 다크 모드로 설정을 하려는데
  • 시스템 기반으로 테마를 토글 하는 기능이 있음을 알게 되었다
  • 그래서 윈도우에서 다크 모드 적용을 알아보았다

윈도우 다크 모드

  • win 키를 누르고 theme를 검색하면 테마 컬러 선택 설정으로 들어갈 수 있다

  • 색 선택에서 어둡게를 선택하면
  • 다크 모드 설정 완료이다
  • 익스플로러나 브라우저를 보면 자동으로 다크 모드가 된 것을 확인할 수 있다
  • 깃허브 사이트나 깃허브 데스크톱 앱도 자동으로 다크 모드로 전환되었다
  • 앱또는 웹사이트마다 일일이 다크 모드 적용하기보다 OS 레벨에서 다크 모드를 적용하는 것이 훨씬 유용하다