해상도 및 스크린 사이즈 대응

목차

들어가면서

이 발표를 통해서 디바이스별 해상도,이해를 더 깊이 할 수 있고, 또한 디바이스 크기별로 UI 를 어떻게 구성할 수 있는지 도움이 되길 바라며 만들어 봅니다!

Pixel 이 뭐징!

pixel = picture (그림) + Element(원소) 의 줄인 말이라고 합니다.
디스플레이를 구성하는 최소 단위!

해상도

우리는 해상도란 말을 많이 쓴다. 그렇다면 해상도는 무엇일까? 뭔가 픽셀과 관련이 있는 것 같은데....
결론부터 말하자면 해상도랑 디스플레이에서 공간을 몇개의 점으로 표현하는가를 나타내는 것이다! 주의할 것은 실제 기기 크기 (Physical device width and height) 와는 다르다는 것!(난 같은건줄)

ppi (pixel per inch)

보통 모니터 출력용의 경우 1인치 안의 픽셀 수인 ppi 를 사용
해상도의 종류

dpi (dots per inch)

보통 인쇄용 이미지는 1인치 안 도트 수인 dpi 를 사용
대충 예를 들어보면 모니터 해상도가 일반적으로 1920 X 1080(Full HD) 해상도를 사용한다. 여기서 800 X 600 해상도로 변경하면 갑자기 화면 안에 있는 것들이 크게 보인다. 왜 그럴까? 1920 X 1080 (약 200만) 개의 점으로 전체화면을 표시하는 것에서 800 X 600 (48만)개의 점으로 표시하는 것으로 변경 되어서 그렇다!

왜 해상도 얘기를 했느냐... 그것은 바로 레티나 디스플레이의 등장이라는 역사로...

해상도 320 X 480 이 평정하던 시대가 있었다. 그러나 2010년 애플은 아이폰4 에 레티나 디스플레이라는 화면 구성을 가져온다! 이는 기존 아이폰 3에 비해 사실상 두배의 해상도(640 X 960)를 갖는 디스플레이였다!
그러나 당시 기존의 앱 / 웹 페이지들이 320 X 480에 최적화 되어 있었다. 그냥 신경 안쓰고 그대로 출시를 했다면 위와 같이 기존에 큰 글씨로 보이던게 조막만하게 변경되어서 보였을 것이다! 그러나 애플은 웹의 경우 device pixel ratio 라는 요소를 가져왔다. 즉, device width 는 320 으로 정해놓고 대신 pixel ratio 의 값을 2로 설정하도록 한 것이다. (예를들어 30 px 의 길이를 지정하면 위에서 얘기한 물리적인 pixel 은 60pixel 이 되는 것!)
여기서 기존의 물리적 pixel 에서 새로운 pixel 의 정의가 생겨나고 말았다!

안드로이드 "우리도...." 그러나....

후발주자 안드로이드는 열심히 애플을 따라가기 바빴다. 때문에 컨텐츠를 잘 그리기 위해 아이폰의 많은 부분을 그대로 차용하는데, device pixel ratio 도 마찬가지였다.
그러나 단일 제조사 애플과 달리 안드로이드는 오픈소스라 여기저기서 기기를 생산했다. 그리고 그 디바이스들이 전부 해상도가 달랐던 것이다!
아이폰이 간단하게 2.0 pixel ratio 를 만든 것 처럼 안드로이드는 간단하게 문제를 해결하기 힘들었다. 다만 device 의 ppi 를 고려해서 1.5, 2.0, 3.0 등 다양한 값을 갖게 되었다. 다만 실제 1.0일 때의 ppi 에 정확히 비례하지 않았고, 실제 단말의 픽셀과도 정확히 일치하지 않게 된다.

근데... 사실 W3C (웹 표준) 에서는...

웹 표준인 W3C 에서는 픽셀에 대한 정의를 Reference pixel 이라고 정의하고 있었다. 애초에 물리 픽셀과 논리 픽셀을 구분해둔 것이다.
일반적으로 모니터는 팔길이 정도의 시야거리(viewing distance)를 갖고 있고 96 dpi 였습니다. 웹 표준을 만들 때 이미 시야거리의 변화와 dpi의 변화를 고려하여 가상의 픽셀인 reference pixel을 정의하고 있었고 웹은 이 값에 기반하여 cm, inch등으로 픽셀값을 변환할 수 있었습니다.
⇒ CSS 에서도 px 는 물리적 px 를 의미하는 것이 아니라 한다!

모바일의 기본 단위 DP 와 PT!

우리는 px, mm 단위와는 친숙하다. 그러나 실제 모바일 환경에서는 어떤 단위가 쓰일까?? 이것을 이해하면 해상도에 대한 대응을 더 잘 할 수 있을 것이다!

개요

안드로이드는 DP, iOS 는 PT 가 기본 단위다.
모바일 가이드라인에서 픽셀 단위를 쓰지 않는 이유는 픽셀의 밀도가 점점 더 좋아지기 때문이다. 같은 크기의 스마트 폰이라도 표현하는 픽셀의 밀도가 다르기 때문이다! 이러한 문제를 해결하기 위해 단위들이 만들어진 것이라 이해하면 좋을 것 같다.

DP

안드로이드의 기본 단위는 DP (density independent pixels)다.

PT

iOS 의 기본 단위는 PT (point)다.
위 두가지는 픽셀 밀도에 따른 고정 단위다.
위 그림과 같이 같은 크기라도 픽셀 밀도가 다르기 때문에 위와 같은 고정단위를 사용하는 것이다.

In React-Native

실제로 RN 에서는...

All dimensions in React Native are unitless, and represent density-independent pixels.
실제 px 등과 같은 단위가 없으며 밀도 독립적인 픽셀을 나타낸다.
적용되는 단위는 iOS에서는 논리 픽셀, 안드로이드 환경에서는 iOS의 논리 pt와 유사한 DIP(DP)

Static Image

@2x and @3x suffixes to provide images for different screen densities ⇒ 해상도에 따라서 다른 이미지를 제공할 수 있다!
. ├── button.js └── img ├── check.png ├── check@2x.png └── check@3x.png <Image source={require('./img/check.png')} /> // RN 알아서!
JavaScript
복사
⇒ 저 해상도엔 저해상도 이미지로, 고 해상도엔 고해상도 이미지로 빌드! 효율성!!

PixelRatio

device pixel density
예시
글꼴 크기의 배율 ⇒ 절대 font size 의 값을 구하기 위한 비율
디바이스에서 세팅한 폰트 스케일도 알 수 있다!
레이아웃 사이즈를 px 변경!

결론

우리는 크게 물리적 pixel 을 신경쓰면서 작업을 하지 않아도 되는 환경이다. 심지어 이미지를 만들어 낼 때도 툴에서 자동으로 해상도에 따른 이미지들을 던져주는 것 같다!
제플린에서 이미지 다운 받으면 이렇게 나오더라는...

음... pixel 독립적인건 알겠는데! 그럼 screen size 에 따른 디자인은 어떻게 하지?

우리가 이제는 물리 pixel 단위를 크게 신경 쓰지 않고 작업을 해도 되는 것은 알겠다. 그런데 그것보다도 디바이스 자체의 크기가 다른 경우에는 어떻게 할 수 있을까?

viewport & font-size scalable unit!

rem? em?

이것은 웹에서 사용되는 단위다! 길이가 유연한 가변 단위. 설정된 폰트 크기에 따라 브라우저에 의해서 픽셀 값으로 변환된다! 자세한 설명은 예시를 보면서!
em 상위 엘리먼트의 폰트 사이즈를 기준으로 적용되는 값
<div font-size="16px"> <div width="1em" height="rem"></div> // 16 x 16 <div> <div font-size="12px"> <div font-size="2em(24px)" width="0.5em" height="0.5em"> // 6 x 6 <div width="1em" height="1em">></div> // 24 x 24 </div> <div>
JavaScript
복사
rem (root em) 최상위 엘리먼트(웹의 경우 html)의 폰트 사이즈를 기준으로 적용되는 값
<html font-size="16px"> <div font-size="10rem"> // 160 x 160 <div width="0.5rem" height="0.5rem"></div> // 8 x 8 <div> <div width="1rem" height="1rem"></div> // 16 x 16 <div>
JavaScript
복사
with media query....
@media screen and (min-width: 769px) { html { font-size: 16px; } } @media screen and (max-width: 768px) { html { font-size: 14px; } @media screen and (max-width: 768px) { html { font-size: 12px; } } // 실제 우리 프로젝트에 사용되는 쿼리! 대충 모바일 사이즈와 핸드폰 사이즈일 때 다르게 하고 싶어서 적용
CSS
복사
⇒ 화면 너비가 769보다 작으면 font-size 14px, 크면 16px! 예시 ⇒ 화면 크기를 늘렸다 줄였다 해보면 변화하는 컴포넌트가 하나 있다. 그게 rem 을 사용한 것이다.

in RN...

앞서 말했다시피 RN 에서는 unitless 한 단위를 사용한다. 오직 밀도 독립적인 픽셀만 사용한다. 그러나 코드를 통해서 아래와 같이 구현은 가능할 것이다!
const screenSize = Dimensions.get("window").width function fontSizer (screenWidth) { if(screenWidth > 320){ return 18; }else if(screenWidth > 250){ return 14; }else { return 12; } } const box = styled.View` width: ${fontSizer(screenSize) * 1}px; => 1rem `;
JavaScript
복사

가변영역(가용영역)을 사용하는 디자인!

위에서 pixel, dp, pt 등등의 개념을 소개했다. 그런데... 사실 모바일 기기들이 모두 동일한 비율과 크기의 dp, pt 로 나오지는 않는다! 때문에 기존과 다른 비율로 나온 스마트폰이 출시되는 순간마다 한 번 더 고심하게 되는 것이다.... 때문에!!! 나온 것이 바로 가변영역을 사용하는 디자인이다!

flex

내부 컴포넌트들이 가용한 공간을 채울 것이다.
위에서 부터 순서대로 flex 를 1, 2, 3 으로 준 것이다.
flex direction 을 바꿀 수도 있다 (기본적으로 세로 방향)
내부 요소들을 정렬할 수 있다.
등등 여러가지 요소가 있지만... 일단 여기선 제외!

percentage

이건 말 그대로.... flex 보다 쉽지!
width: 100% ⇒ 꽉 채운다!
width: 50% ⇒ 반만 채운다!

우리한테 어떻게 적용되면 좋을까? 생각해볼점

디자인이 나왔을 때 가변 길이 디자인인지, 절대 길이 값인지 모르겠다! (예: https://app.zeplin.io/project/5cda231be05b3067d8726e77/screen/5f1595d43a24938c6aae8159/ ⇒ 여기서 화장대 모양의 이미지는 절대 너비를 가지는 것일까? 아니면 margin 빼고는 늘어나는 너비일까? 아마도 이미지니까 절대겠지?? 아마도... https://app.zeplin.io/project/5cda231be05b3067d8726e77/screen/5ef99e1441ad48119499c6b9/ ⇒ 여기서 영상 리스트 목록에서 일단 영상 썸네일 컴포넌트의 width 는 절대일까, 화면 너비에 따라 늘어나는 것일까? 근데 일반적으로 생각해서 늘어나는 뷰로 적용할 것 같다.) 이거 근데 제플린에 이미 있고 되고 있는데 제가 못찾아서 그런걸수도..? 이거 표시가 있나요?
현재 우리는 모바일만 지원하고 있다. 그리고 가로 화면에 대한 지원도 하지 않고있다! 때문에 가로폭이 큰 화면에 대한 예외 케이스 보다 작은 화면에 대한 예외 케이스만 신경을 쓰면 좋지 않을까? (현재 ios5s 기준 screen size 320. 폴더블 폰이 280이 있다는 풍문도 듣기는 했는데... 이 케이스까지는 그냥 패스 해도 될 듯.) 혹시나 먼 훗날 가로폭이 대빵만한 폰이 나오면 그건... 그 때 생각해봐도 될 문제일 듯 하다.
가변 단위(rem) 개념을 사용 가능할 것 같기는 하다! 그러나 실제로 디자인 적으로 체크해볼 사항이 많을 것 같다! (최소 크기 규칙이라던가, 어디어디에 적용할 것인가 등등)

기타

계속 좋아지는 해상도는 왜???

아이폰은 3x 까지 에셋을 뽑아내지만 안드로이드는 4x 까지 뽑아냅니다. 그런데 3x까지의 픽셀만 하더라도 사람이 인지하는 최대 범위라고 합니다! 그렇다면 삼성의 스마트폰의 경우 왜 계속해서 픽셀의 밀도를 높이며 해상도를 높일까요?
제가 읽은 글에서는 아마 VR 때문이 아닐까 하더군요. 스마트폰을 통해서 VR 을 보는 장치의 경우는 순전히 스마트폰 자체의 픽셀을 사용하기 때문에 어지러움증이 발생한다고 합니다. VR 에서의 사람이 인지하는 픽셀 범위는 평면 상의 인지 범위보다 크기 때문이라고 하는군요.

참조