376

Apple's iPad Mini is a smaller clone of the iPad 2 in more ways than we'd want. In JavaScript, the window.navigator object exposes the same values for the Mini and iPad 2. My tests so far to detect the difference have not lead to success.

Why is this important?

As the iPad Mini and iPad 2 screens are identical in pixels but vary in actual size (inches / centimeters), they vary in PPI (pixels per inch).

For web applications and games to offer a friendly user interface, certain elements are adjusted in size relative to a user's thumb or finger position, thus, we may want to scale certain images or buttons to provide for that better user experience.

Things I have tried so far (including some pretty obvious approaches):

  • window.devicepixelratio
  • CSS element width in cm unit
  • CSS media queries (such as resolution and -webkit-device-pixel-ratio)
  • SVG drawings in similar units
  • Doing all sorts of CSS webkit transforms for a set time and counting rendered frames with requestAnimFrame (I was hoping to detect a measurable difference)

I'm fresh out of ideas. How about you?

Update Thanks for the responses so far. I would like to comment on people voting against detecting iPad mini versus 2 as Apple has uhm, one guideline to rule them all. Okay, here's my reasoning why I feel it really makes all sense in the world to know if a person is using an iPad mini or a 2. And do with my reasoning what you like.

The iPad mini is not only a much smaller device (9.7 inch versus 7.9 inch), but its form factor allows for a different usage. The iPad 2 is usually held with two hands when gaming unless you're Chuck Norris. The mini is smaller, but it is also much lighter and allows for gameplay where you hold it in one hand and use another to swipe or tap or whatnot. As a game designer and developer myself, I'd just like to know if it's a mini so I can choose to provide the player with a different controlscheme if I want (for instance after A/B testing with a group of players).

Why? Well, it's a proven fact that the majority of users tend to go with the default settings, so leaving out a virtual thumbstick and putting some other tap-based control on the screen (just giving an arbitrary example here) when the player loads up the game for the first time is what I, and probably other game designers, would love to be able to do.

So IMHO this goes beyond the thick fingers / guidelines discussions and is just something Apple and all other vendors ought to do: allow us to uniquely identify your device and think different instead of following guidelines.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Martin Kool
  • 4,062
  • 4
  • 23
  • 35
  • good question.. even I was looking for a solution. Found nothing on web – AnhSirk Dasarp Nov 06 '12 at 10:08
  • 4
    Best thing is to file a bug with apple http://bugreporter.apple.com If enough people do, there is hope that they will hear us. Current situation is rather disheartening. – William Jockusch Nov 12 '12 at 22:55
  • Can't you use -webkit-min-device-pixel-ratio: ? As for iPhone 4 http://www.mobilexweb.com/blog/iphone4-ios4-detection-safari-viewport#post-15 – Bgi Nov 14 '12 at 13:50
  • 5
    http://konstruktors.com/blog/web-design/4396-detect-ipad-mini-javascript/ – Tzury Bar Yochay Nov 14 '12 at 14:20
  • The most graceful solution, barring an accurate technical one, may be measuring tap precision and throwing up an un-obtrusive prompt, e.g. via a thin top-of-window banner, asking if the user is on an iPad mini when said precision crosses below a threshold. – Felix Nov 14 '12 at 15:32
  • You can check out what art.sy did, they seem to display beautifully on my Mini. I tried to do a similar header and was left with the weird 1px = 2 at a certain space. Edit: They don't solve this necessarily, but they've somehow rendered a great layout. – film42 Nov 14 '12 at 16:34
  • 1
    Hmmm, how about following the HIG instead of trying to do this? This is a waste of time and effort, and sincerely made me sick to read this. Why can't people do stuff the right way? – Elland Nov 14 '12 at 16:47
  • Need your help: I need to capture samples to test my idea the link is in my answer – Avi Marcus Nov 15 '12 at 14:40
  • You should check my response, with it you can calculate the screen size available to the application and place your UI according. – Hoffmann Nov 21 '12 at 19:19
  • Doesn't matter. Users hold iPad minis closer to their face than the full size iPad thus the user sees the content as effectively the same size. – Steve Moser Nov 23 '13 at 17:06

23 Answers23

252

Play a stereo audio file and compare the accelerometer response when volume is high on the right channel and on the left channel - iPad2 had mono speakers whereas iPad Mini has built-in stereo speakers.

Need your help to gather the data please visit this page and help me collect data for this crazy idea. I don't have an iPad mini so I really need your help

Avi Marcus
  • 2,101
  • 1
  • 9
  • 4
  • 35
    You do not think the device blaring out sound when you visit the website is kind of a bad idea? Not to mention people might have their device on silent. No sound would stop this. – flexd Nov 14 '12 at 11:36
  • 1
    iOS audio will only play in response to user generated event (click for example) never when the site loads. And I am not saying it has to be a random noise or very loud the accelerometer on the iDevices since the iPhone 4 is superb a very low sound will probably be sufficient. The sound can be easily integrated into the natural flow of the site, as many sites already do small beeps or play music etc to provide feedback to the user. – Avi Marcus Nov 14 '12 at 12:11
  • 6
    As a slight modification to this: Play a stereo audio file where the right channel is an inverted version of the left channel. With a single speaker, they should cancel and not affect the accelerometer. But either way, relying on speakers + accelerometer is super unreliable. – Kevin Ennis Nov 14 '12 at 13:11
  • 4
    Someone really needs to implement this solution and show the results. – Stephen Eilert Nov 14 '12 at 14:06
  • 14
    Along these lines, on the iPad2, what does `new webkitAudioContext().destination.numberOfChannels` return? – Douglas Nov 14 '12 at 15:27
  • 3
    @flexd you do not think doing device detection is kind of a bad idea? – Ricardo Tomasi Nov 14 '12 at 16:03
  • 2
    @Douglas: I don't have an iPad 2 with a webkitAudioContext-capable version of the firmware to test that theory 100%, but both the iPad Mini and an iPod 4 (which also has a single speaker) return the same answer: 2. One would actually expect this, as if you attach headphones you will be hearing stereo audio. – Jay Freeman -saurik- Nov 14 '12 at 16:42
  • @RicardoTomasi I think doing device detection is a necessary evil. We cannot get around the fact that different devices have different size, capabilities and browsers. But in detecting these devices and doing what needs to be done to optimally display these web pages on the device we should be as little intrusive as possible. Playing a sound to determine if a device is device A or device B is clearly intrusive and annoying. I do think it's a fun and clever suggestion, but it's not really applicable as a solution to the problem at hand. – flexd Nov 14 '12 at 16:52
  • @Douglas, here is what I see on iPad 2: `numberOfChannels = undefined numberOfOutputs = undefined numberOfInputs = undefined context = undefined connect = undefined disconnect = undefined` – Kaspars Nov 14 '12 at 17:34
  • This is beyond what I had hoped for when asking this question. Whether or not Kaspars's availWidth solution works... if this does you're getting the 500 :D – Martin Kool Nov 14 '12 at 19:00
  • @flexd what "needs to be done" are usually wrong assumptions that end up unintentionally breaking things. The mini has the same PPI as the iPhone and a hundred other touch devices, there is no reason to single it out. It also already has features (pinch, tap to zoom) that enable usage of any decently coded existing page. This "solution" is mocking this "need" (I thought I didn't have to explained...) – Ricardo Tomasi Nov 14 '12 at 19:27
  • 2
    @RicardoTomasi Wanting to detect what device is being used does not have to have anything to do with displaying the website itself any different. As someone pointed out earlier the iPad 2 is mostly used with two hands, an iPad mini might work better with one hand. Maybe you want to display different controls in a game based on how the device is most commonly held or something like that. The fact that we can't decide what kind of device is being used is a problem. – flexd Nov 15 '12 at 22:23
  • 1
    Ok guys his answer is funny and all but this is completely not acceptable as a correct answer. Please do not upvote it. – Hoffmann Nov 16 '12 at 19:24
  • @Douglas Tried `numberOfChannels` in an answer below: http://stackoverflow.com/a/13564539/291727 – Alfred Nov 26 '12 at 16:39
  • 2
    just to be clear; would the accelerometer go off because the device rattles along the table, or because the user goes "Woah, what's that noise?!!" and waves it around, scrabbling for mute? – tehwalrus Dec 04 '12 at 09:29
  • I think this answer should get some kind of reward from Apple on the basis of creativity :) I double checked this wasn't answered on April 1st. You are my hero :) @flexd pfff start thinking outside the box :) – Krystian Feb 25 '16 at 21:45
132

Update: It looks like these values are reporting the viewport width and height at the time of tab creation, and they don't change upon rotation, so this method can't be used for device detection!

You can use the either screen.availWidth or screen.availHeight as they seem to be different for iPad Mini and iPad 2.

iPad Mini

screen.availWidth = 768
screen.availHeight = 1004

iPad 2

screen.availWidth = 748
screen.availHeight = 1024

Source: http://konstruktors.com/blog/web-design/4396-detect-ipad-mini-javascript/

Kaspars
  • 1,088
  • 1
  • 9
  • 12
  • 3
    So far looks like the best no-compromise solution. – Morgan Wilde Nov 14 '12 at 13:56
  • I'm wondering about this difference. I thought both use the same resolution? Is the Safari chrome different on these two devices? – Marc Nov 14 '12 at 14:20
  • 10
    This is a detector of how many tabs are open. On my iPad 3 it reports different values when I have more than one tap open, matching the reports on the screen captures. The iPad mini screen capture has two tabs open, while the iPad 2 capture has only one. My iPad 3 reports matching values when I have one or two tabs open. – Mr. Berna Nov 14 '12 at 14:28
  • 7
    No, this is not a detector of how many tabs are open: this is a detector of what orientation the device was open when the tab being used to load this page was first "used". I am not certain whether this is because the size of the viewport is really actually now fixed at that value after you rotate the tab, or if it is simply being cached incorrectly somewhere, but if you sit around and play with multiple tabs in various rotation configurations you can see how it correlates. Where it gets interesting is that if you switch tabs, rotate, and then return to the previous tab and reload, it updates. – Jay Freeman -saurik- Nov 14 '12 at 14:59
  • 1
    Yep, Jay, I did make a similar mistake, misattributing a result to the wrong cause. But my implicit point holds, that this is not a detector for iPad minis, as it will give false positive results on other iPads. – Mr. Berna Nov 14 '12 at 15:21
  • Also who knows how long this approach would work for. Apple could change this in a second – jackslash Nov 14 '12 at 16:02
  • Agreed - this looks like a bug, and therefore the behaviour is very like to change. – Nick Dowell Nov 14 '12 at 16:17
  • Wow, even if this could give false positives, it's such a great find. Will try your testpage tomorrow @Kaspars! – Martin Kool Nov 14 '12 at 19:04
84

I understand this might be a bit low-tech solution, but since we can't seem to come up with anything else yet..

I am assuming you already check for most of the other devices, so I see the following scenarios possible.

You could check for ALL the possible most popular devices that require special CSS/sizing, and if it matches none of those either assume it's an iPad mini or simply ask the user?

// Device checks here
...
else {
  // it would probably be better to make this a nicer popup-thing
  var mini = prompt("Are you using a iPad mini? Press yes for a better user experience");
  // Store the result for future visits somehow.
}

I know that might seem like a stupid approach right now, but if we currently have no way of deciding if the device is a iPad mini or an iPad 2 at least the website will be usable with iPad mini devices doing something like this.

You could even go with something like this:

"To give you the best possible browsing experience we try to detect your device-type to customise the website to your device. Unfortunately due to limitations this is not always possible and we can't currently determine if you use an iPad 2 or an iPad mini by using these methods.

For the best possible browsing experience, please select what device you are using below.

This choice will be stored for future visits to the website on this device.

[] iPad 2 
[*] iPad mini
[] Ancient blackberry device

"

I am not entirely familiar with what you can and can't do client-side in Javascript. I know you can get a user's IP, but is it possible to get a user's mac address? Are those ranges different between iPad2's and iPad mini's?

flexd
  • 829
  • 6
  • 17
  • 25
    I agree so much with this solution. Allowing the user to choose (and potentially change) their device is better than locking them into what you _think_ they want. If you can determine the device fairly accurately; use that as a default, but I think you should always offer a choice - even if it's hidden away in a settings menu. – Liam Newmarch Nov 14 '12 at 09:33
  • 2
    @LiamNewmarch I'm also a big fan of guess and prompt user, rather than assume user preference and lock them in. Sometimes I want to use the desktop site on my iPad. Normally I want to use the English version of a site, regardless of where the damn IP-to-Geo database says I am currently geographically located! you have my upvote sir. – Rebecca Nov 14 '12 at 09:49
  • I think perhaps a combination of @Alessandro Piatti's response and mine would work. You make guesswork using his method, and then you ask the user like I said with whatever the best guess is already checked. Then they could either change it because it's wrong or just press OK to save it :) – flexd Nov 14 '12 at 10:24
  • 7
    Would recommend against using a pop up question however. do a banner like SO does when it auto logs you in. So the user can just read the page if they don't care to answer, rather than being forced out of their mindset to answer a question. – Michael Allen Nov 14 '12 at 10:37
  • 1
    By asking users the question you degrade the user experience enough for Apple to make the change, since that is something the care a lot about. – JiminyCricket Nov 14 '12 at 10:46
  • 9
    -1: I hate pages that ask me questions when I visit them. My response: "Who cares, just show me the content!". The difference between iPad2 and iPad mini is not big enough (IMnsHO) to warrant this approach. JS yes, questions no. – johndodo Nov 14 '12 at 12:46
  • @johndodo The app the OP mentions cares about the thumb location, etc. Their application is likely to have severely degraded experience not just a larger scroll bar. – Joshua Drake Nov 14 '12 at 13:39
  • Speaking in the name of mobile users: mobile developers, please stop using pop-ups of any kind for visitors on mobile devices! It is a big part of what is making mobile web surfing second class in my opinion. – Epaga Nov 14 '12 at 14:29
  • @Epaga The popup was simply a suggestion. I completely agree with you, I just want to view the content. And to be honest I do not even own an iPad or tablet at all. I believe apple might make a change if enough people ask them, and if that fails everyone should implement a red obnoxious pop-up from hell asking them what device they are using. Your websites usability might be compromised for a while but I bet Apple would react fairly quickly and make a change if enough of the bigger websites decided to do something like that. You could do something else like eliminating all other devices? – flexd Nov 14 '12 at 16:57
  • 1
    @JoshuaDrake: I agree that OP's questin is legitimate, I just dislike the idea of questions. Any other solution would be better. Even burying the size setting somewhere would be better. Again, just my (although strong) opinion. :) – johndodo Nov 20 '12 at 20:20
  • @johndodo Do you mean having the setting available somewhere in a menu? If so how would you even make the user aware of the setting? Aren't they more likely to simply decide that the app's experience is terrible and never come back instead of hunting for an unmentioned menu setting? – Joshua Drake Nov 20 '12 at 20:35
  • @JoshuaDrake: I do not propose settings as a solution (I said "**even** burrying..."), I am just strongly disagreeing with *this* solution. For a much better answer see [Mr. Berna's answer](http://stackoverflow.com/questions/13248493/detect-ipad-mini-in-html5/13376079#13380502), or *even* the accepted answer. :) – johndodo Nov 24 '12 at 21:00
74

I know that is a horrible solution, but at the moment the only way to differentiate between an iPad Mini and an iPad 2 is to check its build number and map each build number with the related device.

Let me give you an example: iPad mini, version 6.0, is exposing "10A406" as build number, while iPad 2 is exposing "10A5376e".

This value can be easily obtained through a regex on the user agent (window.navigator.userAgent); that number is prefixed with "Mobile/".

Unfortunately this is the only unequivocal way to detect an iPad Mini; I would suggest to adopt a viewport related approach (where supported, using vh / vw units) to properly display contents on different screen sizes.

Dave L.
  • 41,260
  • 11
  • 56
  • 61
  • 5
    The build number does appear to be the key, but I have noticed the build number may differ depending on the country the device was bought in. For example in Greece the iPad 2 build number appears to be 10A403 instead of 10A5376e, which I also saw from US iPad 2's. I'm guessing the build number for the mini's may also differ. – esjr Nov 14 '12 at 11:15
  • 67
    This solution is incorrect. For some context: the "build number" describes the operating system, and not the hardware. Now, if different devices always had different OS builds, that would be fine, but that has only been true in the past for the first OS release that came with each new device. In this case, 10A406 is the build number for 6.0 for the iPad Mini, and 10A403 was the build number for 6.0 for the iPad 2 (*not* 10A5376e, which was 6.0 beta 4). However, the build number of 6.0.1 on both is already 10A523, so the current build is already identical, and future builds will continue to be. – Jay Freeman -saurik- Nov 14 '12 at 12:29
  • 1
    I fear Jay's correct, checked my data (such as it is) : the build number reflects the OS. – esjr Nov 14 '12 at 12:50
  • 1
    Have you tried this PPI hack? http://stackoverflow.com/questions/279749/detecting-the-system-dpi-ppi-from-js-css - basically create a hidden element with a width of 1 inch, then get the width in pixels. That should resolve your root problem. – JohnLBevan Nov 14 '12 at 13:28
  • @JohnLBevan : that may solve the rendering problem, but what about log analyses etc ? The root problem is with our friends in Cupertino and the push towards 'native' apps. – esjr Nov 14 '12 at 13:35
  • @esjr : Agreed that it doesn't solve the ipad detection issue, but does resolve MartinKool's problem. Also you could use this information to implicitly decide if you've got an ipad 2 or a mini (along with the window.navigator property); and use that data in any logging. The best option is clearly for the vendor to resolve this, but I think this should be a good workaround from our side. – JohnLBevan Nov 14 '12 at 18:48
  • @JohnLBevan That PPI hack seems to just always report 96ppi: http://codepen.io/anon/full/mrfvg – mckamey Nov 16 '12 at 18:49
69

tl;dr Don't compensate for the difference between iPad mini and iPad 2 unless you'll also compensate between fat and skinny fingers.

Apple appears to be deliberately trying not to let you tell the difference. Apple appears not to want us to write different code for the different size versions of iPads. Not being part of Apple myself, I don't know this for sure, I'm just saying that this is what it appears like. Maybe, if the developer community comes up with a fancy detector for iPad minis, Apple may deliberately break that detector in future versions of iOS. Apple wants you to set your minimum target size to 44 iOS points, and iOS will display that in two sizes, the larger iPad size and the smaller iPhone/iPad mini size. 44 points is plenty generous, and your users will certainly know if they are on the smaller iPad, so can compensate on their own.

I suggest stepping back to your stated reason for asking for the detector: adjusting target size for end user comfort. By deciding to design for one size on the large iPad and another size on the small iPad you are deciding that all people have the same size fingers. If your design is tight enough that the difference in size from an iPad 2 and an iPad mini makes a difference, than the size of fingers between me and my wife will make a bigger difference. So compensate for user finger size, not iPad model.

I have a suggestion on how to measure finger size. I'm a native iOS developer, so I don't know if this can be accomplished in HTML5, but here's how I would measure finger size in a native app. I'd have the user pinch two objects together, then measure how close they get together. Smaller fingers will get the objects closer together, and you can use this measurement to derive a scaling factor. This automatically adjusts for iPad size. The same person will have a larger measurement of on screen points on an iPad mini than on an iPad 2. For a game you can call this a calibration step, or not even call it out. Have it as a starting step. For example in a shooting game have the player put the ammo in the gun with a pinching motion.

Mr. Berna
  • 10,151
  • 1
  • 38
  • 41
  • 1
    This first paragraph is the correct answer. The recommended target size of 44 points is perfectly fine. – Ricardo Tomasi Nov 14 '12 at 16:06
  • Man, If I only had a thousand more up votes to give. First paragraph is indeed it, you won the internet. – Mike Nov 14 '12 at 20:44
31

Ask the user to drop their iPad from several thousand feet above the ground. Then use the internal accelerometer to measure the time it takes for the iPad to reach terminal velocity. The larger iPad has a greater drag coefficient and should reach terminal velocity in less time than an iPad Mini.

Here is some sample code to get you started.

function isIPadMini( var timeToReachTerminalVelocity )
{
    return (timeToReachTerminalVelocity > IPAD_MINI_THRESHOLD);
}

You almost certainly need to revisit this code when Apple inevitably releases the next iPad in a different form factor. But I am sure you will stay on top of things and maintain the this hack for each new version of the iPad.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Jason
  • 2,221
  • 17
  • 14
28

Unfortunately, at the moment it seems like this isn't possible: http://www.mobilexweb.com/blog/ipad-mini-detection-for-html5-user-agent

Two days ago, I’ve tweeted about the first detected problem: “It is confirmed that the iPad Mini User Agent is the same as the iPad 2“. I’ve received literally hundreds of answers saying that user agent sniffing is a bad practice, that we should detect features not devices, etc, etc.

Well yes guys, you are right, but it has no direct relationship with the problem. And I need to add the second bad news: there is no client-side technique to make ”feature detection” neither.

BenM
  • 49,881
  • 23
  • 107
  • 158
  • 8
    @net.uk.sweet - Then why don't you edit the answer and fix the mistakes? And btw, the English in the quoted text doesn't seem that bad. – Sandman Nov 14 '12 at 09:52
  • @shi how can you know that the author of that quoted text is an Italian? I'm not native English speaker neither. LOL – Toby D Nov 14 '12 at 10:00
  • "there is no client-side technique to make 'feature detection' neither" is completely false. *feature detection* != *device detection* – Ricardo Tomasi Nov 14 '12 at 16:05
  • @Mytic Moon I've just looked at the original article that is linked in the above post where there is information about the author. – shi Nov 15 '12 at 05:12
26

This is a wild shot, but one of the difference between iPad 2 and iPad mini is that the former does not have a 3-axis gyroscope. Maybe it'll be possible to use the WebKit device orientation API to see what sort of information you can get from it.

For example, this page seems to suggest that you can only get the rotationRate value if the device has a gyroscope.

Sorry I can't give a working POC - I don't have access to an iPad mini. Maybe someone who knows a bit more about these orientation APIs can chime in here.

Assaf Lavie
  • 63,560
  • 33
  • 139
  • 197
  • 3
    So, Apple's website does not describe the gyroscope on the iPad 2 as a "3-axis" gyroscope; but, when they say "gyroscope" they mean a specific kind of part (such that application developers developing games that require that part by the gyroscope capability can rest assured that it is there and will work for them). If you do a Google search for '"3-axis gyroscope" "iPad 2"' you find numerous articles from late 2010 and early 2011 talking about how the iPad 2 is expected to come out with the same 3-axis gyroscope part that the iPhone 4 already had: when it came out, we were not disappointed ;P. – Jay Freeman -saurik- Nov 14 '12 at 12:50
  • This is what I based my suggestion on: http://www.apple.com/ipad/ipad-2/specs.html It doesn't mention any gyroscope. Only "accelerometer". Given that, and the fact that their docs seem to suggest that some devices support only a subset of the motion API, makes this worth a try. I would, if I had an iPad mini... – Assaf Lavie Nov 14 '12 at 13:48
  • 2
    No, seriously: it says "gyroscope" right there in the same small section as "accelerometer". I guess I can post a screenshot of the webpage you just linked with the word "gyroscope" highlighted, but you should be able to find it with ctrl-F. (edit: OK, for humor value, I did that: http://i.imgur.com/8BZhx.png – Jay Freeman -saurik- Nov 14 '12 at 15:07
  • 1
    Well, there really isn't a need to speculate if there really is a difference between the motion API capabilities in the iPad mini and iPad 2. It's just a matter of trying it out and seeing. So, who has an iPad mini here? Regardless, I came to this idea by looking at the tech specs for both devices and searching for differences that may be sensed in HTML/JS. There might be other differences as well. – Assaf Lavie Nov 14 '12 at 18:28
20

Well, the iPad 2 and the iPad Mini have different sized batteries.

If iOS 6 supports it, you can get the current battery level from 0.0..1.0 using window.navigator.webkitBattery.level. At some level either in hardware or software, that is likely calculated as CurrentLevel / TotalLevel, where both are ints. If so, that will result in a float which is a multiple of 1 / TotalLevel. If you take lots of battery level readings from both devices, and calculate battery.level * n you might be able to find a value of n where all the results start to be close to integers, which will give you iPad2TotalLevel and iPadMiniTotalLevel.

If those two numbers are different, and mutually prime, then in production you can calculate battery.level * iPad2TotalLevel and battery.level * iPadMiniTotalLevel. Whichever is closer to an integer will indicate which device is being used.

Sorry about the number of ifs in this answer! Hopefully something better will come along.

Douglas
  • 32,530
  • 8
  • 68
  • 88
18

EDIT 1: My original answer, below, was "don't do it". In the interest of being positive:

The real question, I think, has nothing to do with the iPad X vs. iPad mini. I think it is about optimizing UI element dimensions and placement to the user's ergonomics. You need to determine the size of the user's finger/s in order to drive your UI element sizing and, perhaps, positioning. This, again, is and should probably be arrived at without needing to actually know what device you are running on. Let's exaggerate: Your app is running on a 40 inch diagonal screen. Don't know the make and model or the DPI. How do you size the controls?

You need to display a button that is the gating element into the site/game. I'll leave it up to you to decide where or how it makes sense to do this.

While the user will see this as a single button, in reality it will be composed of a matrix of small tightly packed buttons that is visually covered to appear as a single button image. Imagine a 100 x 100 pixel button made up of 400 buttons, each 5 x 5 pixels. You need to experiment to see what makes sense here and how small your sampling needs to be.

Possible CSS for button array:

.sense_row {
  width:100px;
  height:5px;
  margin:0;
  padding:0;
}

.sense_button {
  float:left;
  width:3px;
  height:3px;
  padding:0px;
  margin:0px;
  background-color:#FF0;
  border:1px solid #000;
} 

And the resulting array:

button array

When the user touches the button array you will, effectively, get an image of the user's finger's contact area. You can then use whatever criteria you want (probably empirically derived) in order to arrive at a set of numbers that you can use to scale and position the various UI elements per your requirements.

The beauty of this approach is that you no-longer care about what device name or model you might be dealing with. All you care about is the size of the user's finger in relation to the device.

I would imagine that this sense_array button could be hidden as part of the entry process into the application. For example, if it is a game, maybe there's a "Play" button or various buttons with the user's names or a means to select what level they'll play, etc. You get the idea. The sense_array button could live anywhere the user has to touch in order to get into the game.

EDIT 2: Just noting that you probably don't need that many sense buttons. A set of concentric circles or buttons arranged like a huge asterisk * might do just fine. You have to experiment.

With my old answer, below, I am giving you both sides of the coin.

OLD ANSWER:

The right answer is: Don't do this. It's a bad idea.

If your buttons are so small that they become unusable on a mini you need to make your buttons larger.

If I have learned anything at all in doing native iOS apps it's that trying to outsmart Apple is a formula for undue pain and aggravation. If they chose to not allow you to identify the device it's because, well, in their sandbox, you shouldn't.

I wonder, are you adjusting the size/location in portrait vs. landscape?

martin's
  • 3,505
  • 6
  • 29
  • 53
  • Wait, did you read the question? _"certain elements are adjusted in size relative to a user's thumb or finger position"_ – Christian Nov 14 '12 at 16:26
  • My question was about whether or not the OP is adjusting elements based on portrait/landscape orientation. Web browsers will auto-adjust to the additional width of landscape and render all content larger than portrait. I am simply trying to point out that --unless you lock everything down-- there's almost no way to optimize for every possible device, orientation and user unless you are writing a native iOS app. Even then you might want to be careful about the choices you make. Could this be done from a web app and javascript? Probably. I just don't think it is a good idea. – martin's Nov 14 '12 at 17:31
  • Ah, I see. Interesting edit too, would be keen to see something like that in practice. – Christian Nov 15 '12 at 11:19
  • 1
    Would a "sense array" like that even work? I would assume iOS would pick whichever cell is closest to where the user touched and only "click" that, not every single cell beneath the user's finger. If it *did* work, that would be pretty damn cool, though. – HellaMad Dec 06 '12 at 23:45
  • No reason for it not to work. It's a bunch of objects that respond to touch events and send messages. – martin's Dec 12 '12 at 03:24
  • Unfortunately, there can't be such thing as a "sense array" as touches are still 1x1px and only actually touch one element at a time. If it could this would be a nice solution, though – fregante Dec 18 '13 at 01:19
11

Yes, it's a good point to check gyroscope. You can easily do it with

https://developer.apple.com/documentation/webkitjs/devicemotionevent

or something like

window.ondevicemotion = function(event) {
    if (navigator.platform.indexOf("iPad") != -1 && window.devicePixelRatio == 1) {
        var version = "";
        if (event.acceleration) version = "iPad2";
        else version="iPad Mini";

        alert(version);
    }
    window.ondevicemotion = null;
}​

Don't have any iPads to test it out.

Cœur
  • 32,421
  • 21
  • 173
  • 232
lc0
  • 654
  • 4
  • 9
  • 12
    This solution does not work (tested on an iPad Mini and an iPad 2: both are detected as "iPad2") as 1) the event.acceleration feature is designed to work if the device has either the fancy gyroscope or the just older accelerometer and 2) according to Apple's website, both the iPad Mini and the iPad 2 have the fancy gyroscope part, so there's no way that the concept of this check would have worked in the first place. – Jay Freeman -saurik- Nov 14 '12 at 12:47
11

What about a micro benchmark, calculate something that takes roughly X microseconds on iPad 2 and Y sec on iPad mini.

It's probably not accurate enough, but there might be some instruction the iPad mini's chip is more efficient at.

Les
  • 2,316
  • 16
  • 17
8

Require all users with the iPad2 user agent to supply a photo using the built in camera and detect the resolution using the HTML File API. iPad Mini photos will be higher resolution due to the improvements in the camera.

You could also play around with creating an invisible canvas element, and convert it to a PNG/JPG using the Canvas API. I don't have any way to test it, but the resulting bits might be different due to the underlying compression algorithm and the device's pixel density.

Vlad Magdalin
  • 1,632
  • 14
  • 17
7

You could always ask the user?!

If the User can't see the buttons or content, then give them a way to manage the scaling themselves. You could always build in some scaling buttons to the site to make the content (text/buttons) larger / smaller. This would be (almost) guaranteed to work for any current iPad resolution and probably any future resolution apple decide they want to make.

TK.
  • 42,559
  • 46
  • 114
  • 145
6

This isn't an answer to your question as posed, but I hope it will be more useful than saying "don't do that":

Instead of detecting the iPad Mini, why not detect that a user is having a hard time hitting the control (or: is consistently hitting in a subregion of the control), and grow / shrink the size of the control to accommodate them?

Users who need bigger controls get them regardless of hardware; users who don't need bigger controls and want to see more content get that too. It's not a simple as just detecting the hardware, and there will be some subtle things to get right, but if it were done carefully it could be really nice.

Stephen Canon
  • 97,302
  • 18
  • 172
  • 256
6

This reminds me of a quote from the movie Equilibrium:

"What, would you say, is the easiest way to get a weapon away from a Grammaton Cleric?"

"You ask him for it."

We're so used to fighting for solutions, when sometimes, it may be better to ask. (There are good reasons that we usually don't do this, but it's always an option.) All of the suggestions here are brilliant, but a simple solution might be to have your program ask which iPad they're using when they start it.

I know that this is kind of a cheeky answer, but I hope it's a reminder that we don't have to fight for everything. (I've braced myself for the downvotes. :P)

Some examples:

  • Keyboard detection during OS installations sometimes can't detect a specific keyboard, so the installer has to ask.
  • Windows asks whether a network you connect to is a home network or a public network.
  • Computers can't detect the person who is about to use it, so they require a username and password.

Best of luck - I hope you find an awesome solution! If you don't, though, don't forget this one.

Community
  • 1
  • 1
jedd.ahyoung
  • 7,450
  • 5
  • 49
  • 89
5

Not answering the question, but the question behind the question:

Your goal is to improve the user experience on a smaller screen. The appearance of the UI controls is one part of it. Another part of UX is the way the application responds.

What if you make the area that responds to taps big enough to be user friendly on the iPad Mini while keeping the visual representation of the UI controls small enough to be visually pleasing on the iPad?

If you have gathered enough taps that were not in the visual area, you can decide to visually scale the UI Controls.

As a bonus, this works for big hands on iPad as well.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Laurens
  • 742
  • 5
  • 9
5

All solutions here are not future-proof (what prevents Apple from releasing an iPad with the same screen size as the iPad 2 but same resolution as the iPad Mini). So I came up with an idea:

Create a div with 1 inch width and append it to the body. Then I create another div with 100% width and append it to the body:

var div1= $("<div/>").appendTo(document.body).width("1in");
var div2= $("<div/>").appendTo(document.body).width("100%");

jQuery width() function always returns values in pixels so you can just:

var screenSize= div2.width() / div1.width();

screenSize now holds the size available to the application in inches (beware rounding erros though). You can use that to place your GUI the way you like it. Also don't forget to remove the useless divs afterwards.

Also note that the algorithm proposed by Kaspars not only will not work if the user runs the application as full screen, but it will also break if Apple patches the browser UI.

This won't differentiate the devices, but as you explained in your edit what you actually wants to know is the device screen size. My idea will also not tell you exactly the screen size, but it will give you an even more useful information, the actual size (in inches) that you have available to draw your GUI.

EDIT: Use this code to check if it actually works on your device. I don't own any iPads to test it on.

var div1= $("<div/>").appendTo(document.body).width("1in").height("1in").css("position", "absolute");
var div2= $("<div/>").appendTo(document.body).width("100%").height("100%").css("position", "absolute");
var width= div2.width() / div1.width()
var height= div2.height() / div1.height()
alert(Math.sqrt(width*width + height*height));

It should popup a window with your screensize in inches. It seems to work on my laptop, returning 15.49 while my laptop screen is marketed as 15.4''. Can anyone test this on iPads and post comments please? Don't forget to run it full screen.

EDIT2: It turns out that the page I tested it in had some conflicting CSS. I fixed the test code to work properly now. You need position: absolute on the divs so you can use height in %.

EDIT3: I did some research, and it seems there is no way to actually get the size of the screen on any device. It's not something the OS can know. When you use a real world unit in CSS it is actually just an estimation based on some properties of your screen. Needless to say that this is not accurate at all.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Hoffmann
  • 12,871
  • 13
  • 69
  • 87
  • Have you tested it? Is 1 inch really the same physical 1 inch on the Mini and iPad? It is possible that 1 inch on the Mini only shows up as 1/2 an inch. – Kernel James Nov 17 '12 at 00:10
  • Tested on iPad 2, 3 and Mini. All three return 3.8125. – Alfred Nov 26 '12 at 10:41
  • @AlfredNerstu wow really? Is this a know Safari bug? Can you test it on safari for mac? – Hoffmann Nov 26 '12 at 11:34
  • @AlfredNerstu sorry the code was wrong, I fixed it now, the page I originally tested it on had some conflicting CSS that made it kinda work. It turns out you need position: absolute on the div to use height values in %. Now that code is giving me 15.49 inches on my 15.4'' laptop on a "clean" page (no css and no elements besides the divs). – Hoffmann Nov 26 '12 at 11:45
  • I tried the new code and now all 2, 3 and Mini all return 9.5. I run the code in a jsfiddle, don't know if that could mess something up? More likely perhaps is that Safari on iOS is made for the 9.7 inch screen and render 1 inch accordingly? – Alfred Nov 26 '12 at 12:34
  • @AlfredNerstu I just checked and jsfiddle uses an iFrame with fixed width/height to run your code, so it will always return the same value no matter where you run it (an iFrame defines a new document.body inside itself). To actually test it on the iPad you can't use it with jsfiddle – Hoffmann Nov 26 '12 at 12:54
  • Also I believe that real world units inside browsers uses some kind of obscure pixel density property hidden in the window object. The name of said property eludes me now – Hoffmann Nov 26 '12 at 13:02
  • Running the code in it's own document returns 16.02 from all three devices. – Alfred Nov 26 '12 at 14:55
  • I also added some color to the divs to be able to see them and it's clear that the 1 inch div1 is rendered smaller on the Mini than the iPad 2. – Alfred Nov 26 '12 at 15:05
  • This seems to be a bug on safari for iOS devices then. On chrome on the desktop it works. – Hoffmann Nov 26 '12 at 16:03
2

Not tested, but instead of playing an audio file and check the balance, it could work to listen to the microphone, extract the background noise, and compute its "color" (frequency graph). If IPad Mini has a different microphone model than IPad 2, then their background color should be measurably different and some audio fingerprinting techniques might help you tell which device is in use.

I don't seriously think it could be feasible and worth the hassle in this specific case, but I think fingerprinting the background noise could be used in some apps, for example to tell you where you are when you are inside a building.

gb.
  • 568
  • 4
  • 11
2

Based on Douglas question about new webkitAudioContext().destination.numberOfChannels on iPad 2 I decided to run some tests.

Checking numberOfChannels returned 2 on iPad mini but nothing on iPad 2 with iOS 5 and 2 as well with iOS 6.

Then I tried to check if webkitAudioContext is available

var hasWebkitAudio = typeof(webkitAudioContext) === "object";
alert(hasWebkitAudio);​

Same here iPad Mini and iPad 2 with iOS 6 returns true while iPad 2 with iOS 5 returns false.

(This test don't work on desktop, for desktop check if webkitAudioContext is a function).

Here's the code for you to try out: http://jsfiddle.net/sqFbc/

Community
  • 1
  • 1
Alfred
  • 7,002
  • 3
  • 23
  • 35
2

What if you created a bunch of 1"x1" wide divs and appended them one by one to a parent div until the bounding box jumped from 1 inch to 2 inches? An inch on the mini is the same size as an inch on the iPad, right?

Scovetta
  • 2,851
  • 1
  • 12
  • 12
  • 1
    So I tried this, but on the mini, an "inch" is smaller than an "inch" on the regular iPad. So this way won't work. – Scovetta Dec 06 '12 at 14:42
2

In iOS7 there is a system-wide setting user can tweak: when things become too small to read, Text Size setting can be changed.

That text size can be used to form UI of plausible dimensions, e.g. for a button (tested on iPad Mini Retina to react to Text Size setting changes):

padding: 0.5em 1em 0.5em 1em;
font: -apple-system-body;    

(sample button CSS, thanks to jsfiddle and cssbuttongenerator)

Srg
  • 472
  • 4
  • 13
1

I am detecting the iPad mini by creating a canvas that is larger an iPad mini can render, filling a pixel then reading the color back out. The iPad mini reads the color as '000000'. everything else is rendering it as the fill color.

Partial code:

function rgbToHex(r, g, b) {
    if (r > 255 || g > 255 || b > 255)
        throw "Invalid color component";
    return ((r << 16) | (g << 8) | b).toString(16);
}
var test_colour = '8ed6ff';
working_context.fillStyle = '#' + test_colour;
working_context.fillRect(0,0,1,1);
var colour_data = working_context.getImageData(0, 0, 1, 1).data;
var colour_hex = ("000000" + rgbToHex(colour_data[0], colour_data[1], colour_data[2])).slice(-6);

I need this for canvas sizing so it's feature detection in my use case.

Community
  • 1
  • 1
SystemicPlural
  • 4,979
  • 7
  • 42
  • 64