Responsive UI is definitely an important part of web and mobile development. When I started working with React Native more than a year ago, I discovered the hard way that there is no functionality out of the box to support responsiveness.

The goal of this article is to show a complete solution that scales RN UI to all sizes and types of screens (phones, tablets etc) and also supports UI scaling even when the app changes orientation.

How React Native works and what are the problems

React Native style properties accept either percentage or independent pixel (dp) values.

Percentage

Percentage is what we know from “normal” web development. The problem with it, is that not all RN style properties accept it. In example: margin , border-width , border-radius and many properties do not accept it as value.

That being said, there is no option for a developer to make their app responsive by coding everything in percentage…

Independent pixels

Independent pixels (dp) on the other hand, are not the classic screen pixels (px) that we become accustomed to as web developers. They mathematically connect to screen pixels and the screen’s scale factor through the following equation:

px = dp * scaleFactor

DP can not be used for responsive UI development as someone might think at this point. That is because scaleFactor actually depends on screen’s pixel density, meaning the number of pixels per inch (ppi). What RN can do though, is that it can scale dp values to screen of different sizes only if they have the same number of ppi. But if you think of Android phones — there are thousands out there and most of them have screens with different ppi even if they come from the same manufacturer!

For more info regarding screens and UI factors, you can have a look at Android’s guide for pixel densities here, Android’s screen compatibility overview and paintcodeapp’s guide for iPhone resolutions.

Let’s come up with a solution — let’s introduce package react-native-responsive-screen

The idea is really simple! Let’s emulate ourselves the percentage effect, and provide the “correct” dp value for every different screen dynamically. We coded that small and easy solution into a package called react-native-responsive-screen.`

UI responsiveness

In order to create responsive UIs, you need to import and use these 2 methods called widthPercentageToDP and heightPercentageToDP . The names are a bit big but they try to be indicative. That being said, both methods accept a string like percentage ( '30%' ) as an argument and return the percentage of the screen’s actual width or height respectively in dp.

Let’s see this with an example. Samsung A5 2017 Android phone, has a width of 360 dp (this is without taking the scale factor into account); so if we code the following:

<View style={{width: widthPercentageToDP('53%') }} />

it will be translated to:

<View style={{width: 190.8} />

because 53% * 360 dp = (53/100) * 360 dp = 190.8 dp. So if you include these 2 methods within your style process, they will automatically find the correct dp values for every single device. And that happens in a performant way; the package makes sure to calculate screen’s width and height once when the app is initialized and every time the methods are used it simply calls these values to make the calculation instead of identifying them again.

Let’s see a 2nd more detailed example:

import React from 'react';

import { StyleSheet, Text, View, Dimensions } from 'react-native';

import {widthPercentageToDP as wp, heightPercentageToDP as hp} from 'react-native-responsive-screen';



export default class App extends React.Component {

render() {

return (

<View style={styles.container}>

<View style={styles.responsiveBox}>

<Text style={styles.text}>This box is always of 84.5% width and 17% height.</Text>

<Text style={styles.text}>Test it by running this example repo in phones/

emulators with screens of various dimensions and pixel per inch (ppi).</Text>

</View>

</View>

);

}

} const styles = StyleSheet.create({

container: {

flex: 1,

backgroundColor: 'gray',

alignItems: 'center',

justifyContent: 'center',

},

responsiveBox: {

width: wp('84.5%'),

height: hp('17%'),

borderWidth: 2,

borderColor: 'orange',

flexDirection: 'column',

justifyContent: 'space-around'

},

text: {

color: 'white'

}

});

What happens here is that we create a simple screen with some text and a view wrapper around it. We code the wrapper’s height to always be the 70% of the screen’s width and the 80% of the screen’s height. Finally we used smaller aliases for the methods’ big names. Check the cross screen result below: