What's dp (density independent pixels) units with CSS?

AndroidCssWeb ApplicationsUser InterfaceScreen

Android Problem Overview


For Android, people recommend using dp (density independent pixels) measurements for UI elements, and there are conventions that exist such as using 48dp for a button height, etc.

I'm working on a web application, and I'm getting a lot of criticism on the UI design saying it does not conform with Android design standards. Obviously, my application is going to look different since it is using CSS and HTML instead of the Android Holo theme, but I would still like to make it conform as much as possible. However CSS does not allow density independent measurements.

When I test my application on different resolutions and pixel densities, it does not look good, and sometimes, it is way out of proportion so it's not even functional. CSS doesn't have dp units like Android native development does, but I was wondering what some alternatives are.

Can I somehow get the pixel density using Javascript and manually scale everything appropriately? What is the best way for making a web app that looks and works nicely on all resolutions/densities?

Android Solutions


Solution 1 - Android

I disagree with the currently accepted answer. As uber5001 suggests, a px is a fixed unit, and in a similar spirit to the efforts of the Android-specifc dp.

Per Material's spec:

> When writing CSS, use px wherever dp or sp is stated. Dp only needs to be used in developing for Android.

Additionally > When designing for the web, replace dp with px (for pixel).

Solution 2 - Android

http://www.w3.org/TR/css3-values/#lengths

The closest unit available in CSS are the viewport-percentage units.

  • vw - Equal to 1% of the width of the initial containing block.
  • vh - Equal to 1% of the height of the initial containing block.
  • vmin - Equal to the smaller of vw or vh.
  • vmax - Equal to the larger of vw or vh.

The only mobile browser to be aware of that doesn't support these units is Opera. http://caniuse.com/#feat=viewport-units

Solution 3 - Android

Use rem.

It is the font size of the root element and a very good base unit for the size of other UI elements.

If one used the same absolute size (in centimeter), the text and other elements would be much too big on mobile or much too small on desktop.

If one used the same amount of pixels, the text and other elements would be much too small on mobile or much too big on desktop.

The rem unit is on spot because it says "Hey, this is how big normal text should be." Basing the size of other UI elements on this is a pretty reasonable choice.

Solution 4 - Android

In CSS3 it may be more accurate to say that the web doesn't have Android's px. The spec for CSS3's px says this:

> pixels; 1px is equal to 1/96th of 1in

px might be the measurement you want, in the future.

Solution 5 - Android

As of CSS3, there are no CSS units that are truly device-independent. See the W3C spec on absolute lengths. In particular, the absolute units might not match their physical measurements. From the spec:

> Note: If the anchor unit is the pixel unit, the physical units might not match their physical measurements. Alternatively if the anchor unit is a physical unit, the pixel unit might not map to a whole number of device pixels.

> Note: This definition of the pixel unit and the physical units differs from previous versions of CSS. In particular, in previous versions of CSS the pixel unit and the physical units were not related by a fixed ratio: the physical units were always tied to their physical measurements while the pixel unit would vary to most closely match the reference pixel. (This change was made because too much existing content relies on the assumption of 96dpi, and breaking that assumption broke the content.)

If physical units were true to their purpose, you could use something like points; points are close enough to dps:

1 in = 72 pt
1 in = 160 dp

1 dp = 72 / 160 pt

If you use SCSS, you can write a function to return in pts:

@function dp($_dp) {
  @return (72 / 160) * $_dp + pt;
}

And use it:

.shadow-2 {
  height: dp(2);
}

Solution 6 - Android

What about a interface based on rem units?

I'm not experienced enough on the matter to confirm, but I think you could make some math based on the viewport size to apply a font-size in the root element and the entire interface would adjust accordingly. This stuff is a bit of witchcraft to me yet.

Solution 7 - Android

Why not use points, it is a consistent size across devices. And is relative to the screen size. Most are not familiar with it since it comes from traditional publishing.

Solution 8 - Android

What about use some mix between vw ( screen's width for any device) and em? Here font-size is changing dynamically, depending your device screen width. Use in your main CSS file next rule:

font-size: calc(100vw * 10 / 375);

(width for iPhone 6/7/8 is 375px, change it to 320px (iPhone5) and etc)

In all cases it is going work perfect. There is only one minus. If your goal is "pixel perfect", then you need to use big numbers after dot.

Example: your goal is font-size h5: 18px on all screens.

Then your perfect "em" will be:

h5 { 
 font-size: 1.79904em;
 }

without perfection use 18 / 10:

h5 { 
 font-size: 1.8em;
 }

According to Google Chrome you get 18.0096px;

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBradView Question on Stackoverflow
Solution 1 - AndroidTohuwView Answer on Stackoverflow
Solution 2 - AndroidcimmanonView Answer on Stackoverflow
Solution 3 - AndroidKonstantin SchubertView Answer on Stackoverflow
Solution 4 - Androiduber5001View Answer on Stackoverflow
Solution 5 - AndroidMihai DanilaView Answer on Stackoverflow
Solution 6 - AndroidDarlan AlvesView Answer on Stackoverflow
Solution 7 - AndroidFranklin MayfieldView Answer on Stackoverflow
Solution 8 - AndroidYuriy IvanochkoView Answer on Stackoverflow