Scaling React Native apps for Tablets

Lets make your React Native app look good on Tablets

If you’ve ever worked on a React Native app then you must’ve wondered how do I make this look good on Tablets. Worry not. This tutorial will teach you how to make your React Native app not look weird on Tablets or lets say any other device.

The Problem

When you make a React Native app, you just make it to work on Mobile Phones. The problem occurs when you try to make it work on Tablets. The reason is Tablets have more pixels than Mobile phones. So whatever dimensions you specify for Mobile are definitely not going to work for Tablets. In short, the bigger your device gets, the more pixels it will have.

From the docs,

All dimensions in React Native are unitless, and represent density-independent pixels. Setting dimensions this way is common for components that should always render at exactly the same size, regardless of screen dimensions.

The Solution

I created a simple Chat App for this tutorial which already looks good on Mobile & we will learn how to scale the app to make it look good on Tablets.

🔗 The complete source code can be found here.

Following picture shows how the App looks when you see it on Mobile (iPhone X) & when you see it on Tablet (iPad Air 2) —

iPhone X (on the left) & iPad Air 2 (on the right) without Scaling

As seen above, the app on Tablet looks very small than on Phone. So we need to scale it to look good on Tablet as well.

Scaling with Flex

Flexbox is helpful while scaling. But, flexbox only scales throughout the entire width or height of the container it is in. It keeps the same proportions among different devices.

Flexbox can scale well if we add some hacks by introducing more containers but its a lot of work.

Also, flex is limited to certain properties like width, height, margin & padding. But we can't use it for some other properties like fontSize, lineHeight or SVGs.

Scaling with Percentages

We can scale our app well using Percentages (%).

React Native v0.42 & above has added support for Percentages (%) but it is only limited to the properties like padding, margin, width, height, minWidth, minHeight, maxWidth, maxHeight, flexBasis.

Other properties like fontSize & lineHeight don't work well with percentages.

Scaling with a Library

React Native Size Matters is a library written by Nir Hadasi which helps us make our scaling easier by providing 3 simple utility functions.

The library is very small & it contains 3 simple utility functions namely —

scale(size: number) — Returns linear scaled result of the provided size, based on your device's screen width.
verticalScale(size: number) — Returns linear scaled result of the provided size, based on your device's screen height.
moderateScale(size: number, factor?: number) — Returns non-linear scale based on a resize factor (defaults to 0.5). If normal scale will increase by +2X, moderateScale will only increase it by +X.

It has some Guideline sizes which are based on ~5" screen mobile devices that makes it easy to scale for bigger devices.

It also has a ScaledSheet method which is a scaled StyleSheet

It uses the following API —

<size>@s — Applies scale function on size
<size>@vs— Applies verticalScale function on size
<size>@ms — Applies moderateScale function with resize factor of 0.5 on size
<size>@ms<factor> — Applies moderateScale function with resize factor of factor on size

Chat App Demo

Now we’re going to use react-native-size-matters in our Basic Chat App.

We’re going to build a simple Chat Wrapper (the one with Yellow & Blue Background) using react-native-size-matters.

Without using react-native-size-matters

Without react-native-size-matters

Using react-native-size-matters

With react-native-size-matters

As you can see the only thing we needed to change was height, padding, margin & fontSize to scale it well across different devices.

Conclusion

The way I like to scale is always try Flexbox in the beginning. Then I try to use Percentages wherever possible. Later, I try to scale the height property vertically using <size>@vs & for everything else I use either <size>@ms or <size>@s.

The example provided in the repo is a little different as I’ve abstracted the common part into a wrapper to make the code more readable. It also has a switch to check how the App would look if react-native-size-matters is not enabled.

The final solution after applying scaling looks like —

iPhone X (on the left) & iPad Air 2 (on the right) with Scaling

You can scan the following QR code to run this app if you have the expo.io client installed on your Android or iOS device:

http://expo.io/@deadcoder0904/react-native-tablets

Have more questions about scaling React Native apps?
Hit me up on Twitter! Don’t be shy to Say Hi 😃