Teetrinker
Teetrinker

Reputation: 850

Line thickness of 0.5px (1 real pixel) on a retina display in mobile safari

How can I draw a line with mobile safari that is one real pixel wide on a retina display?

I tried:

border-bottom:0.5px solid #fff;

and

border-bottom:0.05em solid #fff;

with different values between 0.01em and 0.1em.

Mobile Safari always draws a line that is one pixel wide (2 pixels on a retina display) or none at all. How can I make mobile safari draw a line that is one real pixel (0.5px) wide ?

Upvotes: 6

Views: 8933

Answers (4)

Simon_Weaver
Simon_Weaver

Reputation: 146208

Warning: Many phones are now 3x (3 real pixels for each logical pixel).

Therefore 0.5px mathematically equates to 1.5 real pixels - which is impossible to render consistently.

So if you're trying to put a 0.5px border around something it's physically impossible for it to be consistent. Now the browser may decide to always round it to 1 real pixel or 2 real pixels OR it may try to anti-alias it. Unfortunately not even 'thin' as a thickness renders as one device pixel.

The worse case scanerio is it will use 1 pixel on one edge and 2 pixels on another which will end up looking awful. So be sure to keep this in mind and test on a 3x phone.

Upvotes: 0

Alexandre Dieulot
Alexandre Dieulot

Reputation: 544

Use border-width: 0.5px

Safari 8 (in both iOS and OS X) brings border-width: 0.5px. You can use that if you’re ready to accept that current versions of Android and old versions of iOS and OS X will just show a regular border (a fair compromise in my opinion).

You can’t use this directly though, because browsers that don’t know about 0.5px borders will interpret it as 0px. No border. So what you need to do is add a class to your <html> element when it is supported:

if (window.devicePixelRatio && devicePixelRatio >= 2) {
  var testElem = document.createElement('div');
  testElem.style.border = '.5px solid transparent';
  document.body.appendChild(testElem);
  if (testElem.offsetHeight == 1)
  {
    document.querySelector('html').classList.add('hairlines');
  }
  document.body.removeChild(testElem);
}
// This assumes this script runs in <body>, if it runs in <head> wrap it in $(document).ready(function() {   })

Then, using retina hairlines becomes really easy:

div {
  border: 1px solid #bbb;
}

.hairlines div {
  border-width: 0.5px;
}

Best of all, you can use border-radius with it. And you can use it with the 4 borders (top/right/bottom/left) as easily.

Source: http://dieulot.net/css-retina-hairline

Upvotes: 2

Priit Pirita
Priit Pirita

Reputation: 191

Use scale. The style below will give you hairline

 .transform-border-hairline {
     border-bottom: 1px #ff0000 solid;
     transform: scaleY(0.5);
 }

More specificly (and that trick in live use) here http://atirip.com/2013/09/22/yes-we-can-do-fraction-of-a-pixel/

Upvotes: 4

HeyImArt
HeyImArt

Reputation: 548

I don't normally suggest using .5 in pixels ever really. But you want a fallback to it.

just place the fallback on top. Like this.

border-bottom: 1px solid #fff;
border-bottom: 0.5px solid #fff;

Upvotes: 1

Related Questions