# 개요
Ionic 상에서는 prefers-color-scheme 미디어 속성(쿼리) 라는 표준으로, 사용자 App의 Light/Dark 여부를 판별하여, Theme를 적용한다.
Q. prefers-color-scheme 미디어 속성이란?
prefers-color-scheme CSS 미디어 특성은 사용자의 시스템(크롬, 파이어폭스, 안드로이드 웹뷰, 아이폰 웹뷰)이 App이 라이트 테마나 다크 테마를 사용하는지 탐지하는 데에 사용됩니다.
- prefers-color-scheme 미디어쿼리의 가능 속성
no-preference : 사용자가 시스템에 선호하는 테마를 알리지 않았음을 나타냅니다. 이 키워드는 boolean context에서 false로 판정됩니다.
(특정 브라우저에서는 light로 기본으로 지정됨)
light : 사용자가 시스템에 라이트 테마를 사용하는 것을 선호한다고 알렸음을 나타냅니다.
dark : 사용자가 시스템에 다크 테마를 사용하는 것을 선호한다고 알렸음을 나타냅니다.
- 실제 적용 예시
<div class="themed">Theme</div> //HTML 상에서
.themed { //일반 css 속성 적용(기본이 Dark 형식으로 정의한 듯?)
display: block;
width: 10em;
height: 10em;
background: black; //prefers-color-scheme 속성 값에 따라 변경 가능
color: white; //prefers-color-scheme 속성 값에 따라 변경 가능
}
@media (prefers-color-scheme: light) { //만약 사용자가 light 속성으로 지정했을 경우
.themed {
background: white; //덮어씌우기
color: black; //덮어씌우기
}
}
보통 background 값과 color 값이 반대가 되도록 설계된다.
- 한계
Iexplore 브라우저와 Firefox에서 일부 지원하지 않음
- 대안
/* Fallback for older browsers or manual mode */
body.dark {
/* Dark mode variables go here */
}
<body class="dark"> 추가하여 적용
그러나, light 버전을 사용하려면, 똑같은 대부분의 내용을 또 복사해서 붙여넣어야하는 문제가 발생하므로, 대안이 존재한다.
body {
/* Light mode variables go here */
}
# IONIC 5에서 Dark Theme 적용하기
Light 버전을 따로 작성하는 문제에 대한 해결방안(JS 사용)
별도로, Light 버전을 생각하지 않아도 되는 이유는 속성 정의값 중에 contrast 상태값이 존재하기 때문에, 알아서 대조해서 보여줄 수 있게 된다??
1. theme/variable.scss 안의 body.dark { } 안에 모든 색상값을 정의한다.(primary~ dark, medium,light) 까지 정의해둔다.
1-1. .iOS body.dark {} 안에 별도의 ios에 추가적으로 적용되는 dark theme 속성값을 정의해도 좋다.
1-2. ion-item {
--transition: none;
} //스타일 변경시, flash 효과 없애기 위함(추가적인 옵션이다.)
body.dark {
/* Dark mode variables go here */
} //해당 태그에만 모든 스타일을 작성한다.
2. 일반 <body> 태그 안에 ionic 태그를 사용하여, 작업을 구현한다.(기본 ionic tag는 primary를 따라가기 때문에)
3. 글로벌 JS 파일에 아래의 내용을 적용한다.
// Use matchMedia to check the user preference
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)'); //window 객체상에서 dark 미디어 쿼리 적용 여부 파악
toggleDarkTheme(prefersDark.matches); //현재 상태 값에 따라 스타일 적용
// Listen for changes to the prefers-color-scheme media query
prefersDark.addListener((mediaQuery) => toggleDarkTheme(mediaQuery.matches)); //추후 변경시에도, 스타일 적용(body에 dark 클래스를 제거 또는 추가)
// Add or remove the "dark" class based on if the media query matches
function toggleDarkTheme(shouldAdd) {
document.body.classList.toggle('dark', shouldAdd);
}
In addition to calling toggleDarkTheme() when the app loads and when the media query changes
위와 같이 할 경우, 앱이 로드될 경우 그리고, 미디어 쿼리가 변경될 경우 Theme가 자동으로 적용되는 상태이다.
4. 수동으로 Theme 변경하는 Logic 추가하기(아래의 로직 참조)
// Query for the toggle that is used to change between themes
const toggle = document.querySelector('#themeToggle'); //토글 버튼
// Listen for the toggle check/uncheck to toggle the dark class on the <body>
toggle.addEventListener('ionChange', (ev) => {
document.body.classList.toggle('dark', ev.detail.checked);
}); //토글 변경 이벤트 추가
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)'); //해당 미디어 쿼리가 동작할 수 있는 상황인건지를 확인
// Listen for changes to the prefers-color-scheme media query
prefersDark.addListener((e) => checkToggle(e.matches)); //dark/light 미디어 쿼리 변경 이벤트 추가
// Called when the app loads
function loadApp() {
checkToggle(prefersDark.matches); //선 이벤트 리스너 설정 후, 토글 아이콘이 있는 페이지 로드시 호출
}
// Called by the media query to check/uncheck the toggle
function checkToggle(shouldCheck) {
toggle.checked = shouldCheck;
}
# 몇가지 주의 사항
- 특정 시스템(iOS 브라우저) UI 컴포넌트는 dark mode가 적용이 안될 수 있다.(그래서 ionic 컴포넌트를 주로 사용하길 권장)
color-scheme를 명시해주어야 한다. color-scheme란? 해당 UI 컴포넌트는 dark 또는 light가 될 수 있음을 명시해주는 것이다.
//특정 브라우저에서는 미지원하지만 주로 지원한다.
//App Head 부분에 아래의 HTML을 적용해주면, 알아서 color-scheme를 적용해주고, scrollbar 까지 적용해주므로 유용하다.
<meta name="color-scheme" content="light dark" />
// 또는 style이 미적용된 element 별로 해당 css 속성을 추가해주어도 된다.
color-scheme: light dark;
- 키보드는 dark 스타일 적용이 안된다. 아래의 방법으로 따로 적용은 가능하다.(그러나 굳이?)
키보드 조작예제
import { Platform } from '@ionic/angular';
...
constructor(private platform: Platform) {
this.platform.keyboardDidShow.subscribe(ev => {
const { keyboardHeight } = ev;
// Do something with the keyboard height such as translating an input above the keyboard.
});
this.platform.keyboardDidHide.subscribe(() => {
// Move input back to original location
});
}
Q. CSS란?
Cascading Style Sheets(CSS)는 HTML이나 XML(SVG, XHTML 같은 XML 방언(dialect) 포함)로 작성된 문서의 표현을 기술하기 위해 쓰이는 (스타일을 정의한)스타일시트 언어입니다. CSS는 요소가 화면, 종이, 음성이나 다른 매체 상에 어떻게 렌더링되어야 하는지 기술합니다.
웹 표준 기술로써, 대부분의 브라우저가 표준적으로 제공하며, 표준으로 개발되었다.
Q. 미디어속성이란?
미디어 특성은 사용자 에이전트, 출력 장치, 환경 등의 특징을 나타냅니다. 미디어 특성 표현식은 선택사항이며 특성의 존재 여부와 값을 판별합니다. 각각의 미디어 특성 표현식은 괄호로 감싸져야 합니다.
만약 사용자의 Device의 너비가 400px 이상 일때만 스타일을 따로 적용하고 싶을 떄 사용되는 CSS 상의 표준 기술(?)이다.
- 대표적인 항목
width | 뷰포트 너비. | |
height | 뷰포트 높이. | |
aspect-ratio | 뷰포트 가로세로비. | |
orientation | 뷰포트 방향. | |
resolution | 출력 장치의 해상도. |
- Media Query Level 5에서 추가된 항목
prefers-reduced-motion | 사용자가 줄어든 움직임을 선호함. | Media Queries Level 5에서 추가 |
prefers-reduced-transparency | 사용자가 줄어든 투명도를 선호함. | Media Queries Level 5에서 추가 |
prefers-contrast | 사용자가 시스템에 고대비/저대비를 요청했는지 여부. | Media Queries Level 5에서 추가 |
prefers-color-scheme | 사용자가 밝은 테마나 어두운 테마를 선호하는지 여부. | Media Queries Level 5에서 추가 |
scripting | 스크립트(JavaScript 등)를 사용할 수 있는지 여부. | Media Queries Level 5에서 추가 |
- 사용 예시
@media (height > 600px) {
body { line-height: 1.4; }
}
@media (400px <= width <= 700px) {
body { line-height: 1.4; }
}
# Ionic 5상에서 prefers-color-scheme 미디어 쿼리 설정하기
theme/variables.scss 파일 상에서 아래 부분 수정
@media (prefers-color-scheme: dark) {
:root {
/* dark mode variables go here */
}
}
# 출처
- https://developer.mozilla.org/ko/docs/Web/CSS
- https://developer.mozilla.org/ko/docs/Web/CSS/@media#Media_features
-https://ionicframework.com/docs/theming/dark-mode#automatically-enable-dark-mode
'[DEV] App Dev ∕ Mobile > Framework ∕ Ionic' 카테고리의 다른 글
[Ionic 5] Shadow Dom 이란? (0) | 2020.08.14 |
---|---|
[Ionic 5] Global 전체배경,글자 기본색상값 적용하기 (0) | 2020.08.14 |
[Ionic 5] Main Color 색상 정의하기 (0) | 2020.08.13 |
[Ionic 5] Ionic Infinite Slide (0) | 2020.08.13 |
Ionic 성능개선하기 - Slide 최적화 (0) | 2020.08.12 |
최근댓글