Detecting the iPhone4 and Resolution with Javascript or PHP
The new iPhone4′s retina display presents a new (although nice to have) problem for web developers. How to detect and deliver content to a 300dpi screen. There’s a wealth of information about how retina display works, so I won’t bore you with the specifics, Apple basically put twice as many pixels in the same width and height of the original screen. This means that the resolution is actually 960×640, although it reports to browsers and javascript that it has a screen dimension of 480×320, which is the resolution of the original iPhone (more on this later).
So the iPhone’s retina display is slightly different from a hi-res 960×640 display, it’s actually a 480×320 display with twice as many pixels (crazy huh?). The thinking goes a little like this, the device has a 480×320 “virtual pixels” so when measuring the device using javascript or in code it returns these pixels, however each of these pixels is represented by 2 actual screen pixels on the new device. This enables old web code to be compatible with both devices.
After googling for a long time on how to deliver content to the new device, the best I found was Aral Balkan’s excellent article on the higher DPI and how to use it to deliver higher DPI content (http://aralbalkan.com/3331).
However he talks about using css media queries as outlined by Apple in it’s webkit recommendations:
<link rel="stylesheet" type="text/css" href="/css/retina.css" media="only screen and (-webkit-min-device-pixel-ratio: 2)" />
However if I want to mealy deliver a single image in the normal way using an image tag, I know I can do it through CSS, using SVG and such, but what if I would like to just do a straight detection of the iPhone4, and deliver dynamic content myself. I’d have to somehow detect that the device connecting was a iPhone4 or at least a hi-res device, using a new hi-pixel display. You’d think I’d be able to use the javascript screen or viewport object. However both of these return the “virtual pixel” dimensions not the new ones.
I think Thomas Mair describes the new display in a nice way, when describing why we need custom CSS:
The reason is, that because every pixel is half the visual size, you may have to double the values of many CSS properties. For example text-shadow: 0 1px 0 #fff; which is like a half visual pixel on the iPhone 4. So to make a one-pixel line (better: looks like a one-pixel line) you have to write 2px. This preserves the visual size and adds a very smooth appearance – like we expect it from a Retina display. It also makes huge improvements for layouts on the iPhone 4 possible.
In short the only way I’ve found of getting the actual screen dimensions of the new device is by using the pretty well hidden “window.devicePixelRatio” property so :
<script type="text/javascript">
if( window.devicePixelRatio >= 2 ){
alert( "Hi Res @ Pixel Ratio : " + window.devicePixelRatio + " & Size : " + screen.width * window.devicePixelRatio);
}else{
alert( "Normal @ Pixel Ratio 1 & Size : " + screen.width + "+" + screen.width);
}
</script>
Obviously if you were doing a serious app, you would detect also detect check if the property window.devicePixelRatio exists before doing any computation on it.
But what about PHP, or server side technologies. Well this is were Apple make there second slightly odd choice. When detecting any mobile device from a server most people will use the UserAgent string, to detect the device, and then deliver content. However the iPhone’s user agent is based on the OS and not the device, this may sound like it makes sense, but it bucks a trend made by most other companies who put the model as well as the OS into their device agents. The iPhone 4′s user-agent on iOS4 is exactly the same as the iPhone3GS running the same OS.
iPhone4 & 3GS – Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7
This means the iPhone4 is completely undetectable by PHP and other server side technologies, as they have no way of detecting things like screen width. The only solution is to use Javascript to add the devicePixelRatio to a cookie, this can then be picked up by PHP and used, it’s not clean but until Apple sorts out it’s user-agents, it’s the only way to detect it in PHP.
<?php
if( isset($_COOKIE["pixel_ratio"]) ){
$pixel_ratio = $_COOKIE["pixel_ratio"];
if( $pixel_ratio >= 2 ){
echo "Is HiRes Device";
}else{
echo "Is NormalRes Device";
}
}else{
?>
<script language="javascript">
writeCookie();
function writeCookie()
{
the_cookie = document.cookie;
if( the_cookie ){
if( window.devicePixelRatio >= 2 ){
the_cookie = "pixel_ratio="+window.devicePixelRatio+";"+the_cookie;
document.cookie = the_cookie;
location = '<?=$_SERVER['PHP_SELF']?>';
}
}
}
</script>
<?php
}
?>
16 Responses to Detecting the iPhone4 and Resolution with Javascript or PHP
Leave a Reply Cancel reply
Twitter:
- @FDT5 Cheers :) in reply to FDT5 1 week ago
- @FDT5 No, I mean Mobile Presets : http://t.co/LE5W9C9b in reply to FDT5 1 week ago
- Anyone know how to add extra mobile presets to @FDT5 ?? 1 week ago
- More updates...
Posting tweet...
Friends





Very helpful and informative. (and thorough!) Thanks.
[...] have heard of media queries being used to target mobile devices (based on screen pixel width) or to target the iPhone 4′s Retina display, but you may not have known that you can also target screen [...]
I was googling all over the place trying to find this exact solution. Great post, many thanks!
[...] http://www.bdoran.co.uk/2010/07/19/detecting-the-iphone4-and-resolution-with-javascript-or-php/ Posted by Spiros Spiropoulos Filed in Uncategorized No Comments » [...]
Great post, thanks. Is there a way to detect device orientation using php? I’m guessing not but… it would be great for feeding variable dimensions to embedded videos/images.
E.G.
if (orientation == landscape){
$width = 960;
} else {
$width = 640;
}
echo ”;
Cheers
Dave
You can detect iPhone 4 in PHP with Mobile/8A293
No. That is the build number of software, nothing to do with hardware. My iPod 3G and iPhone 4 have the same Mobile/9A405 (same iOS 5.0.1).
That’s actually a good point..!
Very good article, thank you!
@sexyprout, not true – my iPhone 3GS is coming up with that user agent. I will resort to Ben’s Javascript detection.
Thank you Ben – you are a god among men!!
[...] Detecting the iPhone4 and Resolution with Javascript or PHP : BDoran [...]
@evolutioneer on further investigation the 8A293 tag is merely indicative of an 4.0 OS GM build, and not an iPhone 4 device.
You can do it passing the device pixel ratio as a get parameter of the current page by simply redirecting when the javascript is displayed. then you don’t need cookies enabled, but still javascript.
something like this :
location.replace(location.href + ‘?device_pixel=’+ window.devicePixelRatio);
this is the way i’ll do it
That’s a good point, I passed through the cookie, mainly due to the fact that I build sites with mod_rewrite urls, so using GET vars never usually help as it messes up these URLs.
But you’re right of course, GET is much simpler, and I have used that method on a site before as well.
Another option is to back-call the page with POST as well through Ajax, but that’s probably just silly
Thanks for this.
I was desperately looking for a way to detect iPhone4 or 3….
cheers
It seems that iPhone 4S has fell prey to this same issue
So this code will only tell you whether the connecting device is an iOS device with Retina Display or not, as of now there’s no discernible way of telling the difference between the devices in each category ie:
Pixel Density of 1: iPhone 2G, iPhone 3G & iPhone 3GS
Pixel Density of 2: iPhone 4 & iPhone 4S