React Native Density independent pixels, PixelRatio

Saurabh Gour
4 min readMay 25, 2018

--

Recently, I started working on React Native and came across the term density independent pixels. This term confused me for some time, and after some reading I finally understood what is actually means. Long story short, a density independent pixel ( or a device independent pixel ) is an absolute unit of measurement like inches, centimetres or millimetres. The value for 1 dp equals 1/160 of inch or 0.15875 mm( ref: wiki ). If you are interested in knowing about PixelRatio or the details for dp calculation, you may want to continue reading.

Definition: The android website defines one dp equal to one pixel on a medium-density screen( 160dpi or 160 dots per inch or 160ppi). This definition is sufficient enough for us to calculate the actual value of 1 dp. One inch is an absolute unit of measurement and will not change on any screen with any density. Thus lets imagine we have to arrange 160 small squares (pixels) on a line measuring 1 inch.

Image not to scale, but you get the idea :)

As you can imagine, the only way this can be done is if each of the pixels ( square ) has a side measuring 1/160 inch i.e 0.00625 inches or 0.15875mm. From the definition mentioned above, the value for 1 dp comes out to be 0.15875mm as well.

Different density devices: At the end of the day a device like a mobile, tablet or laptop depends on pixels for the display. A dp is a virtual pixel unit i.e we kind of only use it for our own abstraction. Lets consider, we have a device of 160 dpi having width of 3 inches and height of 5 inches. Since every inch has 160 pixels, we can imagine our device as a grid of squares having 480 pixels horizontally ( 160 * 3 ) and 800 pixels vertically ( 160 * 5). This value 480 * 800 is the resolution of the device. The ratio of the screen width ( also the ratio of number of pixels ) is same which is 5:3 ( or 800: 480 ). For this device, the PixelRatio would be 160dpi( device dpi ) / 160dpi ( base dpi) which comes out to be 1. The get method for PixelRatio in React Native( PixelRatio.get()) should return a value of 1 for a 160 dpi device.

Another api in react native is the Dimensions api. The Dimensions api returns the width and height of the device in dp.

Thus for the above device, we will get a height of 800(dp) and width of 480(dp).

If we are to consider screen dimensions exactly same as those mentioned above [ 3 inches width and 5 inches height ], and a dpi of 320, following would be the calculations. The PixelRatio would now be equal to 320dpi(device dpi)/160dpi(base dpi) [ The base dpi would always be 160dpi]. Thus PixelRatio would be 2.

The interesting thing about dp is that to account for the changes in pixel density, the amount of pixels occupied by one dp changes. [Do note that dp is still absolute, the pixel width is changing, hence only the number of pixels a dp contains is changing ]. So, for the 320 dpi screen, one dp would contain 2 pixels ( i.e the PixelRatio). Since the dimensions of the screen have not changed, its fair to assume that our Dimension api would give the same output for the width and height. Let’s see how.

With 320 dpi, the resolution of the screen would be 960 * 1600 pixels. Since 1 dp now occupies 2 pixels, this resolution would be divided by 2, thus resulting in a screen width and height of 480(dp) and 800(dp).

Different size devices: As we already discussed, the dp is an absolute value,thus for a larger screen size, the Dimensions api should logically yield a higher dp value for width and height.

PixelRatio.roundToNearestPixel(): This method rounds a dp value to the nearest pixel. Lets say for the 320dpi device, we supply the value of 32.4 (dp).For this device, the pixel value of the same would come out to be 32.4 * 2 ( PixelRatio) i.e 64.8. Every pixel needs to be an absolute number since for our abstraction logically we cannot sub-divide a pixel. Thus, the nearest possible pixel value would be found i.e 65 and the corresponding dp value i.e 32.5 ( 65/2 ) would be returned as a result.

Final thoughts: I tested the Dimensions a and PixelRatio api’s on my Google Pixel 2 mobile and found out that there are some very minor variations in the calculated and actual values, however I think they can safely be ignored.

In this article, we have see seen the absolute unit dp which can be used in scenarios where we need the same dimensions across any devices. If the concept still confuses you like it did to me, think of dp like inches or centimetres and you’d be good to go. If you’d like to learn how we can achieve responsive design in react native, this article would be a good place to start.

--

--