├── .gitignore
├── LICENSE
├── README.en.md
├── README.jp.md
├── README.md
├── assets
├── css
│ ├── content.css
│ ├── dark.css
│ └── reset.css
└── js
│ ├── dark.js
│ └── example.js
├── img
├── ani.gif
└── dark-diff.png
└── index.html
/.gitignore:
--------------------------------------------------------------------------------
1 | *.DS_Store
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Seung-hyun Hwang
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.en.md:
--------------------------------------------------------------------------------
1 | # 🌙 Dark Mode Web Page design
2 |
3 | - [한국어](https://github.com/tmdgus0084/apple-dark-mode/blob/master/README.md)
4 | - [English](https://github.com/tmdgus0084/apple-dark-mode/blob/master/README.en.md)
5 | - [日本語](https://github.com/tmdgus0084/apple-dark-mode/blob/master/README.jp.md)
6 |
7 | ## Table of contents
8 | 1. [What is the Dark mode?](#what-is-the-dark-mode)
9 | 2. [Why should we use Dark Mode?](#why-should-we-use-dark-mode)
10 | 3. [Recognizing Dark mode](#recognizing-dark-mode)
11 | 4. [Turn Dark mode on and off](#turn-dark-mode-on-and-off)
12 | 5. [Animation](#animation)
13 |
14 | ## What is the Dark Mode?
15 | On September 20, 2019, at 6:00 p.m., Apple began to release iOS 13, a new operating system for iPhone and iPod Touch. In addition, at WWDC2019 (Apple WorldWide Developers Conference) held in early June of the same year, developers in Apple provided a way that web developers can control Dark Mode for iOS13 and MacOS Mojave. Unlike the previous UI, which shows black letters on the white background, Dark Mode shows white letters on the black background.
16 |
17 | ## Why should we use Dark Mode?
18 | Why should we use Dark Mode? That's because it's in fashion these days and looks cool? There're more fundamental reasons in this question.
19 |
20 | The most important purpose of webpages is to clearly convey information of the webpage to the users. Movie theater staffs turn off the lights in the theater so that they make the inside space dark before the movie starts. That's because the focus on the central contents is likely to be distributed outside when the surrounding elements are too fancy or conspicuous. Therefore, dark environments including Dark Mode allow you to focus more on the central contents than on the surrounding elements because dark things aren't usually fancy or conspicuous. The simple UI design patterns that we use these days are in the same vein.
21 |
22 | Developers have a duty to make software easy for all users to use regardless of whether or not they have disability. Apple's 'VoiceOver' is an accessibility tool, Apple's flagship for blind people, and that's why many blind people choose Apple's iPhone. In addition, the function of "inverting colors" on entire screen is helpful for many users that have low vision or is sensitive to bright lights.
23 |
24 | Likewise, Dark Mode also can have a good effect on users, who have low vision or is sensitive to bright lights, by reducing their eyestrain. You may be anxious that it might be turned into bright colors again when you visit a webpage using Dark Mode with the function of inverting colors turned on, but you don't have to be worried! The function of Apple's "Smart Invert" is working to invert colors of screen in accordance with checking whether or not the webpage is using Dark Mode, and the function doesn't invert the color of the screen when the webpage is using Dark Mode.
25 |
26 | Imagine that a user unlock dark lock screen in his or her smartphone, open dark web browser, and access your web site by entering an address in dark address bar. Oops!! The user whose device is using Dark Mode is very suprised by dazzling lights when the user access your website that isn't supporting Dark Mode. ~Doctor, I can't see at all!!~ Developers have to offer users unified UX. The different UI from the environment of users might make them feel like leaving your website as soon as possible.
27 |
28 | For this reason, I'll tell you how to automatically change the website to dark design when users using Dark Mode access it.
29 |
30 | ## Recognizing Dark mode
31 | You have to check out whether or not the device of users is allowed to use Dark Mode so as to apply Dark Mode the moment users access a website. Here's how you can check for it on CSS and JavaScript:
32 |
33 | #### CSS
34 | CSS supports a `prefer-color-cheme` media query that tells you what kind of theme the device of users has. `prefers-color-cheme` can have the following values:
35 |
36 | - no-preference: Not telling what kind of theme the device has.
37 | - light: Using light mode.
38 | - dark: Using Dark Mode.
39 |
40 | Therefore, you can write CSS codes, which work only for users using Dark Mode, with the code below:
41 | ```css
42 | @media (prefers-color-scheme: dark) {
43 | body {
44 | background: black;
45 | color: white;
46 | }
47 | }
48 | ```
49 |
50 | However, some browsers may don’t support `prefers-color-cheme` media queries and have different values from the settings of system-theme on the device of the users.
51 |
52 | - ✅ : Supporting prefers-color-cheme media queries.
53 | - ❌ : Not supporting them or having different values from the settings of system-theme on the device of users.
54 |
55 | | OS / Browser | Safari | Chrome | Firefox | Whale |
56 | | ------------- |:------:|:------:|:-------:|:-----:|
57 | | iOS |✅ |❌ |❌ |❌ |
58 | | iPadOS |✅ |❌ |❌ |❌ |
59 | | macOS |✅ |✅ |✅ |✅ |
60 |
61 |
62 | #### JavaScript
63 | In JavaScript, after referencing the media query of CSS, you check out whether or not the device of users is supporting the `prefers-color-cheme` media query, determining compatibility of the device.
64 |
65 | ```javascript
66 | const darkModeMeidaQuery = window.matchMedia('(prefers-color-scheme: dark)');
67 |
68 | function updateForDarkModeChange() {
69 | if (darkModeMeidaQuery.matches) {
70 | // Dark mode is on.
71 | } else {
72 | // Dark mode is off.
73 | }
74 | }
75 |
76 | darkModeMeidaQuery.addListener(updateForDarkModeChange);
77 | updateForDarkModeChange();
78 | ```
79 |
80 | You can succeed to support Dark Mode by applying the following code:
81 |
82 | ```css
83 | @media (prefers-color-scheme: dark) {
84 | body {
85 | background: #323232;
86 | color: #fff;
87 | }
88 |
89 | header {
90 | background: #111;
91 | }
92 |
93 | footer {
94 | background: #111;
95 | }
96 | }
97 | ```
98 |
99 | 
100 | All CSS codes associated with Dark Mode are written in one media query. Therefore, you can activate the whole media code of a file by using the attribute of `media` in `link` tag after writing CSS codes in the file of `dark.css`.
101 |
102 | #### dark.css
103 | ```css
104 | /*
105 | media=(prefers-color-scheme: dark)
106 | */
107 |
108 | body {
109 | background: #323232;
110 | color: #fff;
111 | }
112 |
113 | header {
114 | background: #111;
115 | }
116 |
117 | footer {
118 | background: #111;
119 | }
120 | ```
121 |
122 | #### index.html
123 | ```html
124 | ...
125 |
128 | ...
129 | ```
130 |
131 | ## Turn Dark Mode on and off
132 | The recognition function of Dark Mode works only on some browsers and devices, including iOS13, iPadOS, and MacOS Mojave. Dark Mode doesn’t work in case you don't use the latest apple device and the browser which are supporting the function of prefers-color-scheme media query. From now on, I'll tell you how to make Dark Mode available for users who use a device that doesn't support Dark Mode function.
133 |
134 |
135 | You can enable or disable the CSS codes by manipulating the attribute of `media` in `link` tag that you added in order to detach the file. First, make buttons so that you can control `darkModeSwitch`, the function of JavaScript that turns Dark Mode on/off.
136 |
137 |
138 |
139 | ```html
140 |
143 | ```
144 |
145 | そして、先に`dark.css`を読み込むために追加した`link`タグにidを付与します。
146 | ```html
147 |
151 | ```
152 |
153 | 上記に言及した`ddarkModeSwitch`関数を定義します。ここで`link`要素の`media`属性を操作します。
154 | ```javascript
155 | function darkModeSwitch(status) {
156 | document
157 | .querySelector('#dark-mode-sheet')
158 | .setAttribute(
159 | 'media',
160 | status? 'screen' : 'not screen'
161 | );
162 | }
163 | ```
164 |
165 | ダークモードをオフにしてオンにする機能を追加しました。 しかし、ユーザーがウェブページをリフレッシュしたり、他のページに移動したりする場合、ダークモードは解除されます。 この問題は、Cookieを使ってブラウザに設定値を保存し、この設定に従ってウェブページを表示するようにすれば解決されます。
166 |
167 | この文では、クッキーの操作のために`JavaScript Cookie`ライブラリを使用します。
168 | [もっと見る](https://github.com/js-cookie/js-cookie)
169 |
170 | まず、ダークモードに変更するたびに、これをクッキーとして保存します。 クッキーは文字列で値を保存するため、状態値を整数型に変換して保存します。そして、この値を持ってくる関数`isDarkMode`も追加します。
171 | ```javascript
172 | function isDarkMode() {
173 | return Cookies.get('darkmode');
174 | }
175 |
176 | function darkModeSwitch(status) {
177 | Cookies.set('darkmode', +status);
178 | document
179 | .querySelector('#dark-mode-sheet')
180 | //中略
181 | }
182 | ```
183 |
184 | これからはウェブページが始まるときにこの値にしたがってページを操作しなければなりません。 クッキー値がある場合は、ユーザの機器のダークモード設定を無視し、クッキー値にしたがってページを操作します。もしクッキー値がなかったら何の操作もしません。保存された値は定数で成り立つ文字列なので、これを再び整数型に変更します。
185 |
186 | ```javascript
187 | //前略
188 | document.addEventListener('DOMContentLoaded', function () {
189 | const isDm = isDarkMode();
190 | if (isDm != null) darkModeSwitch(+isDm);
191 | });
192 | ```
193 |
194 | ダークモードをすべてのユーザーに完璧にサポートできるようになりました。
195 |
196 | ## アニメーション
197 | ダークモードに変わるたびにアニメーションを追加すると、もっと完成度の高いウェブデザインになります。
198 |
199 | 
200 | ```css
201 | body {
202 | transition: .5s background, .5s color;
203 | }
204 |
205 | header {
206 | transition: .5s background;
207 | }
208 |
209 | footer {
210 | transition: .5s background;
211 | }
212 | ```
213 |
214 | テストに使用されたページは [こちら](https://tmdgus0084.github.io/apple-dark-mode/)をクリックして確認できます。様々なユーザーの経験のために、多くの資料を探索し、発展することを祈ります。この文が役に立ったならスター⭐️をクリックして下さい!
215 | 読んで頂いてありがとうございます.
216 |
217 | ## 寄与者
218 | - [Seung-hyun Hwang@tmdgus0084](https://github.com/tmdgus0084): チーフ・ディレクター
219 | - [Hyunwoo Park@lqez](https://github.com/lqez): 誤文訂正
220 | - [@Bgh0602](https://github.com/Bgh0602): 英語翻訳
221 | - [@sjbhm18](https://github.com/sjbhm18): 韓国語のバージョンの文書を校正して、これを英語と日本語に翻訳。
222 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 🌙 다크모드 웹 페이지 디자인
2 |
3 | - [한국어](https://github.com/tmdgus0084/apple-dark-mode/blob/master/README.md)
4 | - [English](https://github.com/tmdgus0084/apple-dark-mode/blob/master/README.en.md)
5 | - [日本語](https://github.com/tmdgus0084/apple-dark-mode/blob/master/README.jp.md)
6 |
7 | ## 목차
8 | 1. [다크모드란?](#다크모드란)
9 | 2. [왜 다크모드를 사용해야할까?](#왜-다크모드를-사용해야-할까)
10 | 3. [다크모드 인식하기](#다크모드-인식하기)
11 | 4. [다크모드 끄고 켜기](#다크모드-끄고-켜기)
12 | 5. [애니메이션](#애니메이션)
13 |
14 | ## 다크모드란?
15 | 2019년 9월 20일 새벽 2시, 애플은 아이폰과 아이팟 터치를 위한 새로운 운영체제인 iOS 13를 배포하기 시작했습니다. 또한 같은 해 6월 초에 열렸던 WWDC2019(애플 세계 개발자 회의)에서는, 웹개발자가 iOS13과 MacOS Mojave를 위한 다크모드를 제어할 수 있는 방법을 제공했습니다. 흰 바탕에 검은 글씨를 띄우던 기존의 UI와는 달리, 다크모드는 검은 바탕에 흰 글씨를 띄우며 전체적으로 어두운 모습을 보여주는 UI입니다.
16 |
17 | ## 왜 다크모드를 사용해야 할까?
18 |
19 | 우리가 다크모드를 사용해야 할 이유는 무엇일까요? 요즘 유행이라서? 멋져 보여서? 이보다 더 근본적인 이유가 있습니다.
20 |
21 | 웹페이지의 가장 중요한 목적은 웹 페이지의 정보를 사용자에게 명확하게 전달하는 것입니다. 영화관 직원들은 영화가 시작되기 전에 가장 먼저 상영관의 조명을 꺼서 주변을 어둡게 만듭니다. 그 이유는 주변을 꾸미는 요소가 너무 화려하거나 눈에 띄면 중심 콘텐츠에 대한 집중도는 외부로 분산되기 쉽기 때문입니다. 영화관 사례와 마찬가지로, 다크모드를 비롯한 여러 어두운 환경은 주변 요소보다 중심 콘텐츠에 더욱 집중할 수 있도록 해줍니다. 요즘 자주 쓰이는 심플한 UI 디자인 패턴도 이와 동일한 맥락입니다.
22 |
23 | 개발자는 사용자의 장애 여부와 관계없이 모든 사용자가 편리하게 소프트웨어를 사용할 수 있도록 제공할 의무를 가지고 있습니다. 애플의 'VoiceOver'는 시각 장애인을 위한 애플의 대표적인 접근성 도구로, 많은 시각장애인들이 아이폰을 선택하는 이유가 되었습니다. 이밖에도 화면 전체를 반전시키는 '색 반전' 기능이 저시력자나 밝은 빛에 예민한 사용자들에게 많은 도움을 주었습니다.
24 |
25 | 다크모드 또한 저시력자나 밝은 빛에 예민한 사용자에게 눈의 피로를 덜어주는 효과를 주어 큰 도움이 됩니다. 사용자가 색 반전 기능을 켜고 다크모드 웹 페이지에 방문하면 다시 밝은 색이 되지 않을까라고 걱정할지도 모르겠지만, 그럴 필요 없습니다. 애플의 '스마트 반전' 기능은 상황에 따라 적절하게 화면을 반전시키는 기능으로, 이미 다크모드를 지원하고 있다면 화면을 반전시키지 않습니다.
26 |
27 | 한 사용자가 스마트폰의 어두운 잠금 화면을 풀고, 어두운 웹 브라우저를 켜고, 어두운 주소창에 주소를 입력해서 우리 사이트에 접속하고 있습니다. 앗, 기기 자체에서 지원하는 다크모드를 사용하던 이 사용자는 다크모드를 지원하지 않는 우리 사이트에 접속하는 순간 섬광탄을 맞은 느낌을 간접적으로 체험합니다. ~~의사 선생님, 눈이 안보여여~~ 우리 개발자는 사용자에게 통일성 있는 사용자 경험을 제공할 필요가 있습니다. 사용하던 환경과 동떨어진 환경의 UI는 사용자에게 거부감과 우리 사이트에서 한시라도 빨리 떠나고 싶다는 마음을 심어줄 것입니다.
28 |
29 | 이러한 이유로, 이 글에서는 다크모드를 사용 중인 사용자가 웹 사이트에 접속할 경우 자동으로 웹 사이트를 어두운 디자인으로 변경하는 방법을 다룹니다.
30 |
31 |
32 | ## 다크모드 인식하기
33 | 사용자가 웹 사이트에 접속한 순간 다크모드를 적용하려면 우선 사용자의 기기가 다크모드를 사용하고 있는지 확인해야 합니다. CSS와 JavaScript에서 이를 확인하는 방법은 다음과 같습니다.
34 |
35 | #### CSS
36 | CSS는 사용자 기기가 어떤 테마를 사용하는지 알려주는 `prefers-color-scheme`미디어쿼리를 지원합니다. `prefers-color-scheme`는 다음과 같은 값을 가질 수 있습니다.
37 |
38 | - no-preference: 테마를 알리지 않음.
39 | - light: 라이트모드를 사용중임.
40 | - dark: 다크모드를 사용중임.
41 |
42 | 따라서 아래와 같은 코드를 통해 다크모드를 사용중인 사용자에게만 작동하는 CSS 코드를 작성할 수 있습니다.
43 | ```css
44 | @media (prefers-color-scheme: dark) {
45 | body {
46 | background: black;
47 | color: white;
48 | }
49 | }
50 | ```
51 |
52 | 그러나, 일부 브라우저는 `prefers-color-scheme`미디어쿼리를 지원하지 않거나 실제 사용자 기기의 시스템 테마 설정과는 다른 값을 가지고 있습니다.
53 |
54 | - ✅ : 지원함
55 | - ❌ : 지원하지 않거나 시스템 테마 설정과 다른 값을 가짐.
56 |
57 | | OS / Browser | Safari | Chrome | Firefox | Whale |
58 | | ------------- |:------:|:------:|:-------:|:-----:|
59 | | iOS |✅ |❌ |❌ |❌ |
60 | | iPadOS |✅ |❌ |❌ |❌ |
61 | | macOS |✅ |✅ |✅ |✅ |
62 |
63 |
64 | #### JavaScript
65 | JS에서는 CSS의 미디어쿼리를 빌려온 뒤, `prefers-color-scheme` 미디어쿼리 지원여부를 확인하여 호환성을 결정합니다.
66 |
67 | ```javascript
68 | const darkModeMeidaQuery = window.matchMedia('(prefers-color-scheme: dark)');
69 |
70 | function updateForDarkModeChange() {
71 | if (darkModeMeidaQuery.matches) {
72 | // Dark mode is on.
73 | } else {
74 | // Dark mode is off.
75 | }
76 | }
77 |
78 | darkModeMeidaQuery.addListener(updateForDarkModeChange);
79 | updateForDarkModeChange();
80 | ```
81 |
82 | 이제 다음과 같은 코드를 적용해서 다크모드를 지원하는 데 성공했습니다.
83 |
84 | ```css
85 | @media (prefers-color-scheme: dark) {
86 | body {
87 | background: #323232;
88 | color: #fff;
89 | }
90 |
91 | header {
92 | background: #111;
93 | }
94 |
95 | footer {
96 | background: #111;
97 | }
98 | }
99 | ```
100 |
101 | 
102 |
103 | 다크모드와 관련된 CSS 코드는 모두 하나의 미디어쿼리 속에 작성되어 있습니다. 따라서 다크모드의 CSS 코드는 `dark.css`라는 파일에 따로 담아두고 `link` 태그의 `media` 속성을 활용해 파일 단위의 미디어쿼리를 조작할 수 있습니다.
104 |
105 | #### dark.css
106 | ```css
107 | /*
108 | media=(prefers-color-scheme: dark)
109 | */
110 |
111 | body {
112 | background: #323232;
113 | color: #fff;
114 | }
115 |
116 | header {
117 | background: #111;
118 | }
119 |
120 | footer {
121 | background: #111;
122 | }
123 | ```
124 |
125 | #### index.html
126 | ```html
127 | ...
128 |
131 | ...
132 | ```
133 |
134 | ## 다크모드 끄고 켜기
135 | 위에서 언급한 다크모드 인식 문법은 iOS13 이상, iPadOS, MacOS Mojave 이상의 일부 브라우저에서만 작동합니다. 최신 버전의 애플기기가 아니거나 prefers-color-scheme 미디어쿼리 기능을 지원하지 않는 브라우저를 사용하고 있다면 다크모드는 작동하지 않습니다. 아래부터는 다크모드 기능을 지원하지 않는 기기를 사용하는 이용자가 다크모드를 사용할 수 있도록 하는 방법을 다룹니다.
136 |
137 | 앞서 파일을 분리하기 위해 추가한 `link` 요소의 `media` 속성을 조작하는 것으로 해당 CSS를 활성화하거나 비활성화할 수 있습니다. 우선 다크모드를 끄고 켜는 JavaScript 함수를 `darkModeSwitch`라고 하고 이를 조작할 버튼을 만듭니다.
138 | ```html
139 |
44 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
45 |
46 |
47 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
48 |
49 |
50 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
51 |
52 |
53 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
54 |
55 |
56 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
57 |
58 |
59 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
60 |