- λ€ν¬λͺ¨λλ?
- μ λ€ν¬λͺ¨λλ₯Ό μ¬μ©ν΄μΌν κΉ?
- λ€ν¬λͺ¨λ μΈμνκΈ°
- λ€ν¬λͺ¨λ λκ³ μΌκΈ°
- μ λλ©μ΄μ
2019λ 9μ 20μΌ μλ²½ 2μ, μ νμ μμ΄ν°κ³Ό μμ΄ν ν°μΉλ₯Ό μν μλ‘μ΄ μ΄μ체μ μΈ iOS 13λ₯Ό λ°°ν¬νκΈ° μμνμ΅λλ€. λν κ°μ ν΄ 6μ μ΄μ μ΄λ Έλ WWDC2019(μ ν μΈκ³ κ°λ°μ νμ)μμλ, μΉκ°λ°μκ° iOS13κ³Ό MacOS Mojaveλ₯Ό μν λ€ν¬λͺ¨λλ₯Ό μ μ΄ν μ μλ λ°©λ²μ μ 곡νμ΅λλ€. ν° λ°νμ κ²μ κΈμ¨λ₯Ό λμ°λ κΈ°μ‘΄μ UIμλ λ¬λ¦¬, λ€ν¬λͺ¨λλ κ²μ λ°νμ ν° κΈμ¨λ₯Ό λμ°λ©° μ 체μ μΌλ‘ μ΄λμ΄ λͺ¨μ΅μ 보μ¬μ£Όλ UIμ λλ€.
μ°λ¦¬κ° λ€ν¬λͺ¨λλ₯Ό μ¬μ©ν΄μΌ ν μ΄μ λ 무μμΌκΉμ? μμ¦ μ νμ΄λΌμ? λ©μ Έ 보μ¬μ? μ΄λ³΄λ€ λ κ·Όλ³Έμ μΈ μ΄μ κ° μμ΅λλ€.
μΉνμ΄μ§μ κ°μ₯ μ€μν λͺ©μ μ μΉ νμ΄μ§μ μ 보λ₯Ό μ¬μ©μμκ² λͺ ννκ² μ λ¬νλ κ²μ λλ€. μνκ΄ μ§μλ€μ μνκ° μμλκΈ° μ μ κ°μ₯ λ¨Όμ μμκ΄μ μ‘°λͺ μ κΊΌμ μ£Όλ³μ μ΄λ‘κ² λ§λλλ€. κ·Έ μ΄μ λ μ£Όλ³μ κΎΈλ―Έλ μμκ° λ무 νλ €νκ±°λ λμ λλ©΄ μ€μ¬ μ½ν μΈ μ λν μ§μ€λλ μΈλΆλ‘ λΆμ°λκΈ° μ½κΈ° λλ¬Έμ λλ€. μνκ΄ μ¬λ‘μ λ§μ°¬κ°μ§λ‘, λ€ν¬λͺ¨λλ₯Ό λΉλ‘―ν μ¬λ¬ μ΄λμ΄ νκ²½μ μ£Όλ³ μμλ³΄λ€ μ€μ¬ μ½ν μΈ μ λμ± μ§μ€ν μ μλλ‘ ν΄μ€λλ€. μμ¦ μμ£Ό μ°μ΄λ μ¬νν UI λμμΈ ν¨ν΄λ μ΄μ λμΌν λ§₯λ½μ λλ€.
κ°λ°μλ μ¬μ©μμ μ₯μ μ¬λΆμ κ΄κ³μμ΄ λͺ¨λ μ¬μ©μκ° νΈλ¦¬νκ² μννΈμ¨μ΄λ₯Ό μ¬μ©ν μ μλλ‘ μ 곡ν μ무λ₯Ό κ°μ§κ³ μμ΅λλ€. μ νμ 'VoiceOver'λ μκ° μ₯μ μΈμ μν μ νμ λνμ μΈ μ κ·Όμ± λꡬλ‘, λ§μ μκ°μ₯μ μΈλ€μ΄ μμ΄ν°μ μ ννλ μ΄μ κ° λμμ΅λλ€. μ΄λ°μλ νλ©΄ μ 체λ₯Ό λ°μ μν€λ 'μ λ°μ ' κΈ°λ₯μ΄ μ μλ ₯μλ λ°μ λΉμ μλ―Όν μ¬μ©μλ€μκ² λ§μ λμμ μ£Όμμ΅λλ€.
λ€ν¬λͺ¨λ λν μ μλ ₯μλ λ°μ λΉμ μλ―Όν μ¬μ©μμκ² λμ νΌλ‘λ₯Ό λμ΄μ£Όλ ν¨κ³Όλ₯Ό μ£Όμ΄ ν° λμμ΄ λ©λλ€. μ¬μ©μκ° μ λ°μ κΈ°λ₯μ μΌκ³ λ€ν¬λͺ¨λ μΉ νμ΄μ§μ λ°©λ¬Ένλ©΄ λ€μ λ°μ μμ΄ λμ§ μμκΉλΌκ³ κ±±μ ν μ§λ λͺ¨λ₯΄κ² μ§λ§, κ·Έλ΄ νμ μμ΅λλ€. μ νμ 'μ€λ§νΈ λ°μ ' κΈ°λ₯μ μν©μ λ°λΌ μ μ νκ² νλ©΄μ λ°μ μν€λ κΈ°λ₯μΌλ‘, μ΄λ―Έ λ€ν¬λͺ¨λλ₯Ό μ§μνκ³ μλ€λ©΄ νλ©΄μ λ°μ μν€μ§ μμ΅λλ€.
ν μ¬μ©μκ° μ€λ§νΈν°μ μ΄λμ΄ μ κΈ νλ©΄μ νκ³ , μ΄λμ΄ μΉ λΈλΌμ°μ λ₯Ό μΌκ³ , μ΄λμ΄ μ£Όμμ°½μ μ£Όμλ₯Ό μ
λ ₯ν΄μ μ°λ¦¬ μ¬μ΄νΈμ μ μνκ³ μμ΅λλ€. μ, κΈ°κΈ° μ체μμ μ§μνλ λ€ν¬λͺ¨λλ₯Ό μ¬μ©νλ μ΄ μ¬μ©μλ λ€ν¬λͺ¨λλ₯Ό μ§μνμ§ μλ μ°λ¦¬ μ¬μ΄νΈμ μ μνλ μκ° μ¬κ΄νμ λ§μ λλμ κ°μ μ μΌλ‘ 체νν©λλ€. μμ¬ μ μλ, λμ΄ μ보μ¬μ¬ μ°λ¦¬ κ°λ°μλ μ¬μ©μμκ² ν΅μΌμ± μλ μ¬μ©μ κ²½νμ μ 곡ν νμκ° μμ΅λλ€. μ¬μ©νλ νκ²½κ³Ό λλ¨μ΄μ§ νκ²½μ UIλ μ¬μ©μμκ² κ±°λΆκ°κ³Ό μ°λ¦¬ μ¬μ΄νΈμμ νμλΌλ 빨리 λ λκ³ μΆλ€λ λ§μμ μ¬μ΄μ€ κ²μ
λλ€.
μ΄λ¬ν μ΄μ λ‘, μ΄ κΈμμλ λ€ν¬λͺ¨λλ₯Ό μ¬μ© μ€μΈ μ¬μ©μκ° μΉ μ¬μ΄νΈμ μ μν κ²½μ° μλμΌλ‘ μΉ μ¬μ΄νΈλ₯Ό μ΄λμ΄ λμμΈμΌλ‘ λ³κ²½νλ λ°©λ²μ λ€λ£Ήλλ€.
μ¬μ©μκ° μΉ μ¬μ΄νΈμ μ μν μκ° λ€ν¬λͺ¨λλ₯Ό μ μ©νλ €λ©΄ μ°μ μ¬μ©μμ κΈ°κΈ°κ° λ€ν¬λͺ¨λλ₯Ό μ¬μ©νκ³ μλμ§ νμΈν΄μΌ ν©λλ€. CSSμ JavaScriptμμ μ΄λ₯Ό νμΈνλ λ°©λ²μ λ€μκ³Ό κ°μ΅λλ€.
CSSλ μ¬μ©μ κΈ°κΈ°κ° μ΄λ€ ν
λ§λ₯Ό μ¬μ©νλμ§ μλ €μ£Όλ prefers-color-scheme
λ―Έλμ΄μΏΌλ¦¬λ₯Ό μ§μν©λλ€. prefers-color-scheme
λ λ€μκ³Ό κ°μ κ°μ κ°μ§ μ μμ΅λλ€.
- no-preference: ν λ§λ₯Ό μλ¦¬μ§ μμ.
- light: λΌμ΄νΈλͺ¨λλ₯Ό μ¬μ©μ€μ.
- dark: λ€ν¬λͺ¨λλ₯Ό μ¬μ©μ€μ.
λ°λΌμ μλμ κ°μ μ½λλ₯Ό ν΅ν΄ λ€ν¬λͺ¨λλ₯Ό μ¬μ©μ€μΈ μ¬μ©μμκ²λ§ μλνλ CSS μ½λλ₯Ό μμ±ν μ μμ΅λλ€.
@media (prefers-color-scheme: dark) {
body {
background: black;
color: white;
}
}
κ·Έλ¬λ, μΌλΆ λΈλΌμ°μ λ prefers-color-scheme
λ―Έλμ΄μΏΌλ¦¬λ₯Ό μ§μνμ§ μκ±°λ μ€μ μ¬μ©μ κΈ°κΈ°μ μμ€ν
ν
λ§ μ€μ κ³Όλ λ€λ₯Έ κ°μ κ°μ§κ³ μμ΅λλ€.
- β : μ§μν¨
- β : μ§μνμ§ μκ±°λ μμ€ν ν λ§ μ€μ κ³Ό λ€λ₯Έ κ°μ κ°μ§.
OS / Browser | Safari | Chrome | Firefox | Whale |
---|---|---|---|---|
iOS | β | β | β | β |
iPadOS | β | β | β | β |
macOS | β | β | β | β |
JSμμλ CSSμ λ―Έλμ΄μΏΌλ¦¬λ₯Ό λΉλ €μ¨ λ€, prefers-color-scheme
λ―Έλμ΄μΏΌλ¦¬ μ§μμ¬λΆλ₯Ό νμΈνμ¬ νΈνμ±μ κ²°μ ν©λλ€.
const darkModeMeidaQuery = window.matchMedia('(prefers-color-scheme: dark)');
function updateForDarkModeChange() {
if (darkModeMeidaQuery.matches) {
// Dark mode is on.
} else {
// Dark mode is off.
}
}
darkModeMeidaQuery.addListener(updateForDarkModeChange);
updateForDarkModeChange();
μ΄μ λ€μκ³Ό κ°μ μ½λλ₯Ό μ μ©ν΄μ λ€ν¬λͺ¨λλ₯Ό μ§μνλ λ° μ±κ³΅νμ΅λλ€.
@media (prefers-color-scheme: dark) {
body {
background: #323232;
color: #fff;
}
header {
background: #111;
}
footer {
background: #111;
}
}
λ€ν¬λͺ¨λμ κ΄λ ¨λ CSS μ½λλ λͺ¨λ νλμ λ―Έλμ΄μΏΌλ¦¬ μμ μμ±λμ΄ μμ΅λλ€. λ°λΌμ λ€ν¬λͺ¨λμ CSS μ½λλ dark.css
λΌλ νμΌμ λ°λ‘ λ΄μλκ³ link
νκ·Έμ media
μμ±μ νμ©ν΄ νμΌ λ¨μμ λ―Έλμ΄μΏΌλ¦¬λ₯Ό μ‘°μν μ μμ΅λλ€.
/*
media=(prefers-color-scheme: dark)
*/
body {
background: #323232;
color: #fff;
}
header {
background: #111;
}
footer {
background: #111;
}
...
<link rel="stylesheet"
href="assets/css/dark.css"
media="(prefers-color-scheme: dark)">
...
μμμ μΈκΈν λ€ν¬λͺ¨λ μΈμ λ¬Έλ²μ iOS13 μ΄μ, iPadOS, MacOS Mojave μ΄μμ μΌλΆ λΈλΌμ°μ μμλ§ μλν©λλ€. μ΅μ λ²μ μ μ νκΈ°κΈ°κ° μλκ±°λ prefers-color-schemeΒ λ―Έλμ΄μΏΌλ¦¬ κΈ°λ₯μ μ§μνμ§ μλ λΈλΌμ°μ λ₯Ό μ¬μ©νκ³ μλ€λ©΄ λ€ν¬λͺ¨λλ μλνμ§ μμ΅λλ€. μλλΆν°λ λ€ν¬λͺ¨λ κΈ°λ₯μ μ§μνμ§ μλ κΈ°κΈ°λ₯Ό μ¬μ©νλ μ΄μ©μκ° λ€ν¬λͺ¨λλ₯Ό μ¬μ©ν μ μλλ‘ νλ λ°©λ²μ λ€λ£Ήλλ€.
μμ νμΌμ λΆλ¦¬νκΈ° μν΄ μΆκ°νΒ link
Β μμμΒ media
Β μμ±μ μ‘°μνλ κ²μΌλ‘ ν΄λΉ CSSλ₯Ό νμ±ννκ±°λ λΉνμ±νν μ μμ΅λλ€. μ°μ λ€ν¬λͺ¨λλ₯Ό λκ³ μΌλ JavaScript ν¨μλ₯ΌΒ darkModeSwitch
λΌκ³ νκ³ μ΄λ₯Ό μ‘°μν λ²νΌμ λ§λλλ€.
<p>
Dark Mode:
<a onclick="darkModeSwitch(true)">ON</a>
/
<a onclick="darkModeSwitch(false)">OFF</a>
</p>
κ·Έλ¦¬κ³ μμμ dark.css
λ₯Ό λΆλ¬μ€κΈ° μν΄ μΆκ°ν link
νκ·Έμ idλ₯Ό λΆμ¬ν©λλ€.
<link id="dark-mode-sheet"
rel="stylesheet"
href="assets/css/dark.css"
media="(prefers-color-scheme: dark)">
μμμ μΈκΈν darkModeSwitch
ν¨μλ₯Ό μ μν΄μ€λλ€. μ¬κΈ°μ link
μμμ media
μμ±μ μ‘°μν κ²μ
λλ€.
function darkModeSwitch(status) {
document
.querySelector('#dark-mode-sheet')
.setAttribute(
'media',
status? 'screen' : 'not screen'
);
}
μ΄λ ΅μ§ μκ² λ€ν¬λͺ¨λλ₯Ό λκ³ μΌλ κΈ°λ₯μ μΆκ°νμμ΅λλ€. νμ§λ§ μ¬μ©μκ° μΉ νμ΄μ§λ₯Ό μλ‘κ³ μΉ¨νκ±°λ λ€λ₯Έ νμ΄μ§λ‘ μ΄λν κ²½μ° λ€ν¬λͺ¨λλ ν΄μ λ©λλ€. μ΄ λ¬Έμ λ Cookieλ₯Ό μ¬μ©ν΄ λΈλΌμ°μ μ μ€μ κ°μ μ μ₯νκ³ μ΄ μ€μ μ λ°λΌ μΉ νμ΄μ§λ₯Ό νμνλλ‘ νλ©΄ ν΄κ²°λ©λλ€.
μ΄ κΈμμλ μΏ ν€μ μ‘°μμ μν΄Β JavaScript Cookie
Β λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©ν©λλ€.Β
μμΈν보기
μ°μ λ€ν¬λͺ¨λλ‘ λ³κ²½ν λλ§λ€ μ΄λ₯Ό μΏ ν€λ‘ μ μ₯ν©λλ€. μΏ ν€λ λ¬Έμμ΄λ‘ κ°μ μ μ₯νκΈ° λλ¬Έμ μνκ°μ μ μνμΌλ‘ λ³νν΄μ μ μ₯νμμ΅λλ€. κ·Έλ¦¬κ³ μ΄ κ°μ κ°μ Έμ€λ ν¨μ isDarkMode
λ μΆκ°ν©λλ€.
function isDarkMode() {
return Cookies.get('darkmode');
}
function darkModeSwitch(status) {
Cookies.set('darkmode', +status);
document
.querySelector('#dark-mode-sheet')
//μ€λ΅
}
μ΄μ μΉ νμ΄μ§κ° μμλ λ μ΄ κ°μ λ°λΌ νμ΄μ§λ₯Ό μ‘°μν΄μΌ ν©λλ€. μΏ ν€κ°μ΄ μλ€λ©΄ μ¬μ©μ κΈ°κΈ°μ λ€ν¬λͺ¨λ μ€μ μ 무μνκ³ μΏ ν€κ°μ λ°λΌ νμ΄μ§λ₯Ό μ‘°μν©λλ€. λ§μ½ μΏ ν€κ°μ΄ μλ€λ©΄ μλ¬΄λ° μ‘°μλ νμ§ μμ΅λλ€. μ μ₯λ κ°μ μ μλ‘ μ΄λ£¨μ΄μ§ λ¬Έμμ΄μ΄λ―λ‘ μ΄λ₯Ό λ€μ μ μνμΌλ‘ λ³κ²½ν΄μ€λλ€.
//μ λ΅
document.addEventListener('DOMContentLoaded', function () {
const isDm = isDarkMode();
if (isDm != null) darkModeSwitch(+isDm);
});
μ΄μ λ€ν¬λͺ¨λλ₯Ό λͺ¨λ μ¬μ©μμκ² μλ²½νκ² μ§μν μ μκ² λ©λλ€.
λ€ν¬λͺ¨λλ‘ λ³ν λ μ λλ©μ΄μ μ μΆκ°νλ©΄ λμ± μμ±λ μλ μΉ λμμΈμ΄ λ©λλ€.
body {
transition: .5s background, .5s color;
}
header {
transition: .5s background;
}
footer {
transition: .5s background;
}
ν μ€νΈμ μ¬μ©λ νμ΄μ§λ μ¬κΈ°λ₯Ό λλ¬ νμΈν μ μμ΅λλ€. λ€μν μ¬μ©μμ μ¬μ©μ κ²½νμ μν΄ λ λ§μ μλ£λ₯Ό νμνκ³ λ°μ νκΈΈ κΈ°μν©λλ€. μ΄ κΈμ΄ λμμ΄ λμλ€λ©΄ μ€νβοΈλ₯Ό λλ¬μ£ΌμΈμ! κ°μ¬ν©λλ€.
- Seung-hyun Hwang@hsh2001: νλ‘μ νΈ μ΄κ΄
- Hyunwoo Park@lqez: μ€νμ μμ
- @Bgh0602: μμ΄ λ²μ
- @sjbhm18: μμ΄ / μΌλ³Έμ΄ λ²μ λ° λ¬Έμ₯ κ°μ