dp vs px vs pt: Understanding Mobile Screen Units

A developer's guide to density-independent pixels, points, and physical pixels — the unit systems that keep mobile interfaces consistent across hundreds of different screen densities.

8 min read·Updated May 2026·App Image Kit

Why Mobile Developers Cannot Just Use Pixels

On the desktop web in the early 2000s, one pixel meant one physical dot on the screen. Designers could specify a button at 200px wide and be confident it would appear roughly the same size on every monitor. That assumption collapsed with the arrival of high-density mobile displays.

A modern flagship phone packs over 500 pixels per inch into a 6-inch panel, while a budget tablet may use only 160 pixels per inch across a 10-inch screen. If you define a toolbar as 48 physical pixels tall, it will be comfortably tappable on the low-density tablet but microscopically small on the flagship phone. The toolbar needs to occupy the same physical space on both devices — roughly 7-8 mm — regardless of how many hardware pixels fill that space.

This is the core problem that density-independent units solve. Android uses dp (density-independent pixels), iOS uses pt (points), and Flutter uses logical pixels. Each system provides an abstraction layer that translates a single authored value into the correct number of hardware pixels for the device at hand. Understanding how these units relate to one another — and to raw physical pixels — is essential for shipping interfaces that look correct everywhere. For a broader overview of screen density concepts, see the complete guide to DPI.

Physical Pixels (px): The Hardware Dots

A physical pixel is a single light-emitting element on a display panel. The total number of physical pixels defines the device's native resolution (for example, 2556x1179 on the iPhone 15 Pro). This count varies dramatically between devices: a budget Android handset might have a 720x1600 display, while a flagship foldable exceeds 2176x1812 on its inner screen.

When image assets are rendered on screen, they ultimately map to physical pixels. A 192x192 px PNG occupies exactly 192 hardware dots in each direction, no matter what logical unit the layout system uses. This is why you must export raster assets at multiple resolutions — the layout says "48dp icon" but the GPU needs a concrete pixel grid to sample from.

The density of these pixels — how many fit into one inch — is expressed as DPI (dots per inch) or PPI (pixels per inch). This single number is the bridge between logical units and physical output. A deeper explanation is available in the What is DPI? guide.

Density-Independent Pixels (dp/dip): Android's Abstraction

Android defines dp (also written dip) as a virtual pixel unit anchored to a 160 DPI baseline. On a device running at exactly 160 DPI (the mdpi bucket), 1 dp equals exactly 1 physical pixel. On higher-density screens the system multiplies by the appropriate scale factor.

The conversion formula is straightforward:

px = dp * (dpi / 160)

Android groups devices into named density buckets, each with a fixed scale factor relative to mdpi:

BucketDPIScale Factor1 dp =
ldpi~1200.75x0.75 px
mdpi~1601x1 px
hdpi~2401.5x1.5 px
xhdpi~3202x2 px
xxhdpi~4803x3 px
xxxhdpi~6404x4 px

When you specify a touch target as 48dp, Android renders it at 48 px on an mdpi device, 72 px on hdpi, 96 px on xhdpi, 144 px on xxhdpi, and 192 px on xxxhdpi. The physical size stays roughly the same — about 7.6 mm — across all of these screens. For a complete breakdown of the drawable folder structure that Android uses to select the right asset for each bucket, see the Android drawable sizes guide.

Points (pt): iOS's Unit System

Apple's equivalent to dp is the point. One point equals one pixel on the original non-Retina iPhone (163 PPI, designated @1x). Retina displays doubled this to @2x (2 px per pt), and Super Retina tripled it to @3x (3 px per pt).

The relationship is simple:

px = pt * scale_factor

@1x: 1 pt = 1 px   (legacy non-Retina)
@2x: 1 pt = 2 px   (Retina — most iPhones and all iPads)
@3x: 1 pt = 3 px   (Super Retina — iPhone Plus/Pro Max)

Functionally, iOS points and Android dp are nearly identical concepts. Both represent roughly 1/160 of an inch (Apple's baseline is 163 PPI, Android's is 160 DPI — the 2% difference is negligible). A 44pt tap target in iOS guidelines corresponds closely to Android's 48dp minimum touch target. For the full list of icon sizes Apple requires at each scale factor, see the iOS app icon sizes guide.

Logical Pixels in Flutter

Flutter uses the term logical pixel as its layout unit, and it is conceptually equivalent to Android's dp. Flutter exposes the device's density via MediaQuery.of(context).devicePixelRatio. A device pixel ratio of 3.0 means each logical pixel maps to a 3x3 grid of physical pixels.

Because Flutter renders its own pixel buffer (via Skia/Impeller) rather than delegating to platform widgets, it handles density scaling internally. You author layouts in logical pixels, and the engine multiplies by the device pixel ratio when rasterizing. Asset resolution works the same way: provide 1.5x, 2.0x, 3.0x, and 4.0x variants in your asset directories, and Flutter picks the closest match.

CSS Pixels on the Web

Web developers encounter the same density problem through window.devicePixelRatio. A CSS pixel is a logical unit — on a MacBook Pro with a 2x Retina display, one CSS pixel corresponds to four physical pixels (2x2). The browser abstracts this so that width: 48px in CSS occupies roughly the same physical space regardless of screen density.

This makes CSS pixels directly analogous to dp and pt. The mapping is approximately:

  • 1 CSS px = 1 dp = 1 pt (at each platform's reference density)
  • devicePixelRatio = device pixel ratio in Flutter = scale factor in iOS

If you are coming from a web background, the mental model transfers directly: anywhere you wrote CSS pixel values, substitute dp (Android) or pt (iOS) and the behaviour is essentially the same.

Unified Conversion Table

The following table shows how a single logical value (dp or pt) translates to physical pixels at each density tier. The values are equivalent across Android, iOS, and Flutter for practical purposes.

Android BucketiOS ScaleRatio24dp/pt48dp/pt64dp/pt
mdpi@1x1x24 px48 px64 px
hdpi-1.5x36 px72 px96 px
xhdpi@2x2x48 px96 px128 px
xxhdpi@3x3x72 px144 px192 px
xxxhdpi-4x96 px192 px256 px

Practical example: a 48dp button occupies 48 px on mdpi, 72 px on hdpi, 96 px on xhdpi, 144 px on xxhdpi, and 192 px on xxxhdpi. Despite the pixel count varying by 4x, the button remains approximately the same physical size on each device.

sp: Scale-Independent Pixels for Text

Android introduces one more unit for text sizing: sp (scale-independent pixels). An sp behaves exactly like a dp, except that it also scales with the user's preferred font size setting in system accessibility options.

If a user sets their system font scale to 1.3x (large text), a 16sp label becomes 16 * 1.3 = 20.8 dp, which then converts to physical pixels at the device density. This two-stage scaling ensures text remains readable for users with vision impairments while layouts authored in dp stay geometrically stable.

The rule of thumb: use sp for text sizes and dp for everything else (margins, padding, icon dimensions, touch targets). Never use sp for spacing or non-text elements, as that would cause layout instability when the user adjusts their font preference.

iOS handles dynamic text sizing differently via the UIFontMetrics API and Dynamic Type system, but the principle is the same: text units should respect user accessibility preferences while layout dimensions remain fixed.

When to Think in dp vs px

The distinction is simple once internalized:

  • Layout dimensions — always in dp (or pt on iOS). Margins, padding, component sizes, spacing grids.
  • Image assets — always in px. The file on disk is a pixel grid; you export a separate file at each density.
  • Text sizes — sp on Android, Dynamic Type on iOS, rem/em on the web.
  • Stroke widths and borders — dp, but be aware that 1dp renders as a fractional pixel on hdpi (1.5px), which can cause aliasing. Many designers use 1px hairline borders via platform-specific APIs.

When designing image assets, your source file should be created at the highest density you intend to support (typically xxxhdpi/4x) and then exported downward. This ensures maximum sharpness on every device. Tools like App Image Kit automate this multi-density export from a single source image.

Common Confusion Points and Mistakes

Confusing dp with px in asset dimensions

A frequent beginner mistake is exporting an icon at 48x48 px and assuming it will look correct at all densities. On an xxhdpi device, that 48 px icon gets stretched to fill a 144 px space, resulting in visible blurriness. Always export assets at the pixel dimensions required for each density bucket.

Using dp for image dimensions in design specs

Design tools like Figma typically work in logical units (equivalent to dp/pt). When a designer specifies a "48x48 icon," they mean 48 dp — the developer must export it at 48, 72, 96, 144, and 192 px for the respective density buckets. Miscommunication here is one of the most common sources of blurry assets.

Assuming dp and pt are interchangeable constants

While 1 dp and 1 pt represent approximately the same physical size, they are not defined identically. Android's baseline is 160 DPI; Apple's is 163 PPI. For most practical purposes the difference is negligible, but it can become noticeable at very large layout dimensions. Cross-platform frameworks like Flutter and React Native handle this normalization internally.

Forgetting sp for text on Android

Using dp instead of sp for text sizes means your app ignores the user's accessibility font preference. This is both a usability failure and a compliance issue — Google Play's accessibility guidelines explicitly require that text respects the system font scale.

Hard-coding pixel values for different screen sizes

Density and screen size are independent axes. A phone and a tablet can share the same density bucket (both xhdpi) but have vastly different screen dimensions. Use dp for element sizing and responsive layout techniques (ConstraintLayout, Auto Layout, Flex) for overall structure.

Summary: Choosing the Right Unit

Use CaseAndroidiOSFlutterWeb
Layout / spacingdpptlogical pxCSS px
Text sizespDynamic Typelogical px + textScaleFactorrem / em
Image assetspx (per bucket)px (per @Nx)px (per ratio)px (srcset)

Mastering these units eliminates an entire class of visual bugs — blurry icons, incorrectly-sized touch targets, and text that ignores accessibility settings. Design in logical units, export assets in physical pixels at every required density, and let the platform handle the conversion at runtime.

To generate all density variants of your image assets from a single source file, try App Image Kit — it handles the math and exports every size you need, instantly and privately in your browser.

Ready to export your assets?

App Image Kit generates all density variants from a single source image — free, private, and instant.