모바일 앱에서 디스플레이는 매우 소중한 자원이기 때문에 최대한 활용하여야 한다. 그러나 다양한 운영체제와 사이즈의 모바일 기기가 있고, 화면 방향 또한 손쉽게 변경할 수 있다. 따라서 화면을 구성할 때에는 모든 기기의 사용자가 정상적인 환경에서는 불편함 없이 사용할 수 있도록 이를 고려하여야 한다.
모바일 환경에서 화면의 크기는 다양한 물리적 제약, 적어도 무게와 손의 크기를 사유로 특정한 사이즈 내외에서 유지되는 경향이 있다. 그러나 더 선명한 화면 표현을 위한 해상도 증가는 지금까지 유의미하게 진행되어 왔다.
이 때, 화소의 단위인 픽셀을 기준으로 작업할 경우, 물리적으로 화면크기가 고정된 상황에서 해상도가 2배 증가할 경우, 기존 앱 내의 작업물의 크기는 절반으로 줄어들게 된다. 이렇게 될 경우, 텍스트, 버튼, 이미지 등 많은 요소가 같은 해상도라고 해도 정상적으로 이용할 수 없게 되므로 모바일 환경에서는 화소단위로 컨트롤 하지 않고, 물리적 단위(보통, 화면사이즈에 주로 쓰이는 inch 또는 기타 imperial / metric system)를 단위로 하는 작업단위를 가진다.
최종수정일 : 2023.08.29
여기서 말하는 실질 단위란, 물리적 단위의 개입 없이 화면 자체가 개념적으로 표현되는 단위들을 나타낸 것이다. 현실의 길이 단위들에 의해 영향을 받지 않는다.
픽셀은 화소의 단위를 가리킨다. 한 픽셀은 색상, 밝기, 점멸 등 시각표현요소가 동일하며, 개념적으로 단일한 물리 객체이다.
Family & Model | Logical Width | Logical Height | Physical Width | Physical Height | PPI | Scale Factor | Screen Diagonal |
---|---|---|---|---|---|---|---|
iPhone 14 Pro Max | 430 | 932 | 1290 | 2796 | 460 | 3 | 6.7" |
iPad Air (4th gen) | 820 | 1180 | 1640 | 2360 | 264 | 2 | 10.9" |
iPhone 8 | 375 | 667 | 750 | 1334 | 326 | 2 | 4.7" |
Logical Width / Height
Scale Factor가 적용되었을 때, 화면이 몇 pt로 이루어져있는지 표현한다.
예를 들어, Scale Factor가 2인 경우, Logical Width는 Physical Width의 절반이 된다.
Physical Width / Height
실질적으로 화면이 몇개의 픽셀을 가지는지 설명한다.
Scale Factor
pt - px간 비율
표현 단위 수준에서는 개념적으로 존재하는 실질 단위가 현실 세계의 단위들에 맞추어 인간이 이용할 수 있는 실질적인 사이즈로 변환된다.
Android에서는 DPI(Dots Per Inch 단위를 사용한다. 72DPI의 경우 1 inch의 길이 내에 72개의 픽셀이 일렬이 존재할 수 있다.
개수가 많을 수록 고밀도이며 안드로이드에서 주요 DPI는 아래와 같다.
ldpi : 120dpi
mdpi : 160dpi (Default)
hdpi : 240dpi
xhdpi : 320dpi
xxhdpi : 480dpi
xxxhdpi : 640dpi
dp(Density-Independent Pixel)
혹자는 Device Pixel이라고 하기도 하는 듯 하다.
dp는 기준 해상도인 160dpi(mdpi)의 1/160으로, 실질 길이로는 1/160 inch인 0.15875mm를 나타낸다. 따라서 1dp의 길이는 160dpi에서는 1px을, 320dpi에서는 2px을 포함한다.
iOS에서는 PPI(Pixels Per Inch) 단위를 사용한다. 72PPI의 경우 1 inch의 길이 내에 72개의 픽셀이 일렬로 존재할 수 있다.
포인트(pt)
포인트는 1 inch를 최초의 맥 수준의 PPI인 72로 나눈 것으로, 72 pt = 1 inch가 되는 물리적 단위이며 실제로 0.3528mm의 물리적 길이이다.
웹 환경에서는 1pt = 1px로 사용하기도 하며, 이 경우 16pt인 텍스트는 16화소의 높이를 가진다.
현재에는 72PPI이상의 해상도를 가져 각 화소가 1pt보다 작아졌으므로, 0.5pt와 같은 표현도 가능하다.
이 때, 각각 다른 값의 PPI를 가진 환경에서 같은 pt를 가진 객체를 표현하기 위해 @2x, @3x 등의 배수기호를 사용하기도 한다.
리액트 네이티브에서는 기본적으로 안드로이드의 dp(0.15875mm)를 사용한다.
리액트 네이티브에서는 또한 해상도 등의 화면 수치와 관련된 API로 PixelRatio
를 제공한다.
사례 코드
import React from 'react'; import { Image, PixelRatio, ScrollView, StyleSheet, Text, View, } from 'react-native'; const size = 50; const cat = { uri: 'https://reactnative.dev/docs/assets/p_cat1.png', width: size, height: size, }; const App = () => ( <ScrollView style={styles.scrollContainer}> <View style={styles.container}> <Text>Current Pixel Ratio is:</Text> <Text style={styles.value}>{PixelRatio.get()}</Text> </View> <View style={styles.container}> <Text>Current Font Scale is:</Text> <Text style={styles.value}>{PixelRatio.getFontScale()}</Text> </View> <View style={styles.container}> <Text>On this device images with a layout width of</Text> <Text style={styles.value}>{size} px</Text> <Image source={cat} /> </View> <View style={styles.container}> <Text>require images with a pixel width of</Text> <Text style={styles.value}> {PixelRatio.getPixelSizeForLayoutSize(size)} px </Text> <Image source={cat} style={{ width: PixelRatio.getPixelSizeForLayoutSize(size), height: PixelRatio.getPixelSizeForLayoutSize(size), }} /> </View> </ScrollView> ); const styles = StyleSheet.create({ scrollContainer: { flex: 1, }, container: { justifyContent: 'center', alignItems: 'center', }, value: { fontSize: 24, marginBottom: 12, marginTop: 4, }, }); export default App;