Aug 21

How to fix the broken iPad form label click issue

Categories:
JavaScript
Tags:
form, ipad, iphone, javascript, label
Published:
2:33am on Saturday 21st August, 2010

I love my iPad. It’s almost perfect. If only I could click on form labels! Here is how I fixed that particular niggle with some judicious use of of JavaScript.

Updated 23/08: Created a jQuery version - see the bottom of this article for the code!

If, like me, you love some semantic HTML markup, it’s likely that your form elements—input, select, textarea—are marked up something like this:

<label for="your_name">Your name:</label>
<input type="text" id="your_name" name="your_name" 
  size="20" maxlength="20">

You might wrap the input inside the label, but the result is the same—clicking on the label will give focus to the text field so you can start typing (or select/check it in the case of radio buttons and checkboxes). If you’re particularly clever you might even be able to string together a relatively coherent sentence involving Fitt’s Law—but all that falls apart when it comes to Mobile Safari.

Labels in Mobile Safari

Mobile Safari, the browser found on iPhones, iPod Touches and the iPad, does not (currently) implement the same label behaviour as other browsers. Clicking on labels doesn’t do anything—possibly, as Ben Darlow suggests, it is because it would interfere with the tap-to-select-text functionality, although personally I think that usability trumps obscure text-selection use cases.

What’s even weirder is that, in over an hour of googling, I couldn’t find a single reference to this issue. Surely someone, somewhere must have noticed that clicking or tapping on labels in forms on iPad doesn’t select the input? I resolved that when I published a fix for the issue, it would include a couple of clunky sentences stuffed with as many keywords related to the tap click form label input select checkbox radio button problem as possible…

Enable iPad or iPhone users to activate your form elements when they tap on a label

Here is a simple script that does just that.

Very simply, it collects all the labels on the page, then loops through them and applies an onclick event (which the iPad triggers when you tap on an element). The event looks for a for attribute, figures out what sort of form element it relates to, and performs the correct action; either focusing on the element (text inputs, dropdowns and textareas) or toggling the selected state of checkboxes and radio buttons.

There is a test page here where you can try the script on your own iPhone or iPad. If you have an alternative method, or more efficient way to code it, please let me know in the comments. If someone wants to knock up a jQuery plugin as well, that would be nice, as I’ve forgotten how to do it…

As we only need to call the function for the affected platforms, just do something like this (using your document.ready event of choice):

if (navigator.userAgent.match(/iPhone/i) || 
  navigator.userAgent.match(/iPod/i) || 
  navigator.userAgent.match(/iPad/i)) {
	iPadLabels.fix();
}

(And don’t forget that, if and when Apple fix this “bug”, to remove the script.)

jQuerified

And here’s a version of the code in jQuery instead - obviously you need to have the library loaded in your page as well.

Original photo by Phantomfies

I'd love to hear what you think - please use the form below to leave your comments. Anything I consider too offensive, off-topic, or spammy will be deleted at my discretion. Some HTML is permitted, or you can use Textile.

Commenting is not available in this weblog entry.
  1. Jeremy Keith's Gravatar

    Jeremy Keith at 7:10pm on 21st August, 2010 #

    Very handy. I remember using something similar back in the day for the original desktop version of Safari (version 1?) which also didn’t support labels.

  2. trovster's Gravatar

    trovster at 7:22pm on 21st August, 2010 #

    I noticed this the other day when quickly testing something at work. Tried clicking the label to no avail. I assumed someone else must have noticed that it didn’t work and had plugged a JavaScript fix, but apparently not!

  3. Byron's Gravatar

    Byron at 10:23pm on 25th August, 2010 #

    Any word on when Apple will be fixing this? I’m disappointed labels were overlooked.

  4. Thomas Edwards's Gravatar

    Thomas Edwards at 6:26am on 27th August, 2010 #

    The input, select or textarea should always be inside the label tag, as mentioned in the specs from the W3C for XHTML and HTML5. Also, most versions of Internet Explorer handle things like checkboxes poorly if the checkbox is not inside the label. For example in Internet Explorer 7 and 8, if you check the checkbox by pressing the box, not the label it will not fire any JavaScript commands – you should always place them inside the label tag.

  5. Igor's Gravatar

    Igor at 1:21pm on 23rd September, 2010 #

    Excellent article, thanks to author!

  6. Ben Hull's Gravatar

    Ben Hull at 12:12pm on 24th September, 2010 #

    I ran into this today, too - it seems like such a glaring omission that there must be a reason for it (Ben’s text selection idea maybe, but you’re right - that seems weird).

    Thomas - I don’t having the input inside the label is mandated in the specs, mainly because it’s valid (and very useful) to provide multiple labels to a single input.

    I seem to remember that structure causing problems with screen readers, too - though that’s an old memory.

  7. Andre's Gravatar

    Andre at 2:57am on 23rd October, 2010 #

    Thanks for posting this, it’s good logic but this script does not seem to work when tested on the ipad. As far as my research goes, click events added to certain text based elements like labels will be trumped by copy and paste selection functionality of safari mobile. If others are having success with this please share some more insight.
    As far as i know the only text based elements that register click are <a> tags with an href attribute. I had to wrap the label in a <a href=”#”> in order to capture a click to run my logic on.

  8. Matthew Pennell's Gravatar

    Matthew Pennell at 1:37pm on 23rd October, 2010 #

    @Andre: It’s working fine for me (just tested again on my iPad). Clicks on the labels select their corresponding form elements.

  9. Andre's Gravatar

    Andre at 10:05pm on 25th October, 2010 #

    Ok thanks a bunch for confirming, I appreciate that. I’ll look into my particular situation some more then to see where the hang up is.

  10. Colleen's Gravatar

    Colleen at 9:51am on 26th October, 2010 #

    While in the process of modifying your (life-saving) script to work with non-label elements, I discovered an even shorter fix. Tested on iPhone 3GS, iPhone 4 and iPad. I’m sure there are a dozen better ways to write this, but in the meantime stopPropagation() is working perfectly…

  11. Colleen's Gravatar

    Colleen at 10:12am on 26th October, 2010 #

    Whoops… didn’t realize HTML in comments was enabled.
    Demo page here:

    http://deleri.com/checkbox.html

    It feels deceptively simple… am I missing something?

  12. Matthew Pennell's Gravatar

    Matthew Pennell at 9:28pm on 26th October, 2010 #

    Wow, great find Colleen!

    The only drawback I can see is if you are relying on event delegation to pick up the click event further up the DOM; by stopping propagation you will not call any functions bound to parent elements or the document itself.

  13. hypest's Gravatar

    hypest at 3:48am on 29th October, 2010 #

    hmm, I probably found yet a simpler solution… Tested it in the iPad/iPhone emulator…

    just define the onlick handler of the label!!

    example: <label>

  14. hypest's Gravatar

    hypest at 3:51am on 29th October, 2010 #

    (sorry.. posting again, more friendly for this comment system this time)

    hmm, I probably found yet a simpler solution… Tested it in the iPad/iPhone emulator…

    just define the onlick handler of the label, even an empty one!

    example: ... label onclick = [removed] ; ...

  15. Davide Molin's Gravatar

    Davide Molin at 6:23am on 1st December, 2010 #

    @Thomas
    I’ve never put the input fields INSIDE their corresponding label tags. I find it unpractical, un-aesthetic and semantically incorrect.
    Where did you read that the input should be ‘inside’ the label tag ??? It’s not mentioned anywhere.. on the contrary, if you look at the specs from W3C you see exactly the opposite:
    http://www.w3.org/TR/WCAG20-TECHS/H44.html.

    Anyway, the label “for” attribute exists precisely to link the label to the input tag. If the input tag were supposed to be ‘inside’ the label, it would not make any sense to link the two with an attribute.

    Last thing: It’s simply UNTRUE that in IE7-8 the click event is not fired if you put the checkbox “outside” of the label!!

  16. Davide Molin's Gravatar

    Davide Molin at 6:36am on 1st December, 2010 #

    Let me be more precise:

    These are the specs for HTML 4.01:

    http://www.w3.org/TR/1999/REC-html401-19991224/interact/forms.html#h-17.9.1

    in which you can also see that a form control can be associated with more than one label; Containment should be even impossible in that scenario.

    It’s true than you “can” insert an input control “inside” the label; but It’s not mandatory and it’s not even suggested. Doing that, moreover ,creates a strict coupling between the two, making impossible any other association and impacting even over layout.

    Obviously, you’re free to do that.. but, for what ?  ;)

  17. Matthew Pennell's Gravatar

    Matthew Pennell at 2:51pm on 1st December, 2010 #

    @Davide:

    It has always been the case that you have had the option of putting form elements inside their LABEL tag; semantically it creates an implicit relationship between the two (and some browsers then no longer need the for attribute if the label wraps the element), and aesthetically it makes no difference - and can sometimes make it easier to style the element.

    Thomas was incorrect to state it should “always be inside the label tag,” but it’s equally wrong to claim it can never be written that way.

  18. Davide Molin's Gravatar

    Davide Molin at 3:52pm on 1st December, 2010 #

    yeap, you’re right.
    It’s better to simply state the two options available.

    Still, I have to remain in my position about the layout. It “makes” difference to use containment. It simply screws up your layout. I’ve tried it for you: A label and an Input field.
    Try to align the two using simply float:left (because you want them side by side, for example);

    This is the style:

      <style>
          #containment,
          #no_containment {
            margin: 10px 0;
            overflow:hidden;
          }

          #containment label,
          #containment input,
          #no_containment label,
          #no_containment label {
            float:left;
          }
      </style>

    And this is the markup:

      <div id=‘containment’>
          <label >Some Label:
            <input type=“text” value=“val” size=“15” />
          </label>
      </div>
     
      <div id=‘no_containment’>
          <label>Some Label:</label>
          <input type=“text” value=“val” size=“15” />
      </div>

    If you use containment you get a wrong layout: the input field “precedes” the label.. this goes against the hierarchical structure and what you expect. That’s why I state that using containment force you to hack your CSS and has impact on your layout.

    Beside that, you’re right. Freedom is paramount and we are always free to choose the solution that we see fit for the problem at hand.

  19. Matthew Pennell's Gravatar

    Matthew Pennell at 4:43pm on 1st December, 2010 #

    Of course, using float won’t work in that case. But you could set a width on the label, right padding, and then position the input absolutely at the top-right of its container.

    There is always more than one way to skin a cat. :)

  20. Davide Molin's Gravatar

    Davide Molin at 5:16pm on 1st December, 2010 #

    LOL :D I like the one on the ‘cat’ :D

    It’s obviously something that can be solved, nothing to object about it.

    But, alas, you see.. only one attribute in my stylesheet (float:left) and 3 or more in your (absolute positioning, width, right padding…) to get to the same result.
    What code is more maintainable in the long run ? ;p

    (I’ve to tell you: because I’m terribly lazy and I’ve really bad memory I prefer clean and simple code in my stylesheets; ohh yeahh)

    Cheers,
    Dav

  21. albert's Gravatar

    albert at 12:05pm on 5th December, 2010 #

    the most recent comments regarding wrapping form controls with labels confirms my first thoughts as i was reading your post…most developers overlook labels in general, let alone all the benefits gained from developing with their intricacies. this is a gem of a find/solution. nicely done.
    segue: you don’t have to wrap your form controls in labels, but why not? set both to display block and you have a solid structure to style without adding markup bloat to the page. the only control that you cannot explicitly wrap are checkbox inputs, in this case, that input comes first.
    i have found some cross-browser-compatibility issues when wrapping textarea’s but have not followed up with sufficient testing to confirm or not.

  22. Leonard Lin's Gravatar

    Leonard Lin at 1:50pm on 27th January, 2011 #

    As a point of interest, I was able to get selection working w/ radio boxes jQuery simply by focusing on iOS 4.2.1 (iPad).  The code in this case reduces quite simply:


    $(‘label[for]’).click(function() {
      $($(this).attr(‘for’)).focus();
    });

  23. Trent Ahrens's Gravatar

    Trent Ahrens at 5:43am on 24th February, 2011 #

    Or even better:
    $(”*”).delegate(“label”, “click”, $.noop);

    There is also an issue with :active pseudo class not getting used on iOS and this will fix that:
    $(”*”).live(“touchstart”, $.noop);

    The idea is this counters iOS selection logic so click events are dispatched. adding onclick=”” to the tag will also work.

  24. Emma's Gravatar

    Emma at 11:16pm on 11th March, 2011 #

    Thanks for posting, I’m also surprised that there isn’t much information about this via Google search.

    Nice fix.

  25. Vincent Young's Gravatar

    Vincent Young at 1:23am on 15th September, 2011 #

    Noticed that this script does not account for form fields within a label.  This could work:

    http://www.webhipster.com/testing/accessibility/labeltouch/

  26. jon's Gravatar

    jon at 3:50am on 9th November, 2011 #

    the only issue i have with this is it is causing the keyboard to duck and then reappear very quickly if a previous input type=“text” was selected.

    input1 gets focus.
    keyboard appears
    label2 is clicked
    input 1 blurs
    keyboard hides
    script calls input2.focus()
    input 2 receives focus
    keyboard shows.

    ... better than nothing but still subideal in the world of “why doesn’t it work like every other browser on earth including ie 6.”

  27. statinternet's Gravatar

    statinternet at 4:26pm on 18th January, 2012 #

    I used the below code to do it, but it seems have some issues.

    if (navigator.userAgent.match(/iPhone/i) ||
      navigator.userAgent.match(/iPod/i) ||
      navigator.userAgent.match(/iPad/i)) {
      iPadLabels.fix();
    }

  28. Bobby Marko's Gravatar

    Bobby Marko at 12:21pm on 20th January, 2012 #

    Here’s a much simpler fix:
    label { cursor: pointer; }

    Source:
    http://stackoverflow.com/questions/4142520/label-not-clickable-in-jqtouch

  29. Vincent Young's Gravatar

    Vincent Young at 12:45pm on 20th January, 2012 #

    Bobby,

    cursor:pointer is not working for me.  On http://www.webhipster.com/testing/accessibility/labeltouch/ my 3rd example tries this technique and fails.  Can you show me an example of this technique working?

    Thanks.

    -Vincent

  30. Jason Chandler's Gravatar

    Jason Chandler at 12:51am on 21st January, 2012 #

    I’m using iOS 5 on my iPhone and cannot replicate the issue described in this article. All labels are wrapping my inputs, textareas and selects. Tapping the label works as expected.

    You can see it on my not yet launched site here: http://dtigraphics.net/contact

  31. Matthew Pennell's Gravatar

    Matthew Pennell at 2:49am on 21st January, 2012 #

    Maybe it’s been fixed for iOS5, then?

  32. RaphaelDDL's Gravatar

    RaphaelDDL at 2:58am on 26th January, 2012 #

    I tested on iOS 5.0.1 and still does not work. But i’ve found a good workaround.

    With jQuery, use $(‘label’).click(function(){});

    The empty function does the work.

  33. Jan Van Lysebettens's Gravatar

    Jan Van Lysebettens at 4:42pm on 16th February, 2012 #

    works great, thanks for this fix.

  34. Jason's Gravatar

    Jason at 2:57pm on 23rd February, 2012 #

    This is a very good explanation of a solution to a seemingly bizarre problem. I looked over your code and It looks like you’re attaching a event to [each] label… It would be better to use event delegation and attach the event to the <form>. Then you’re only registering a single click event.

  35. Josh's Gravatar

    Josh at 12:12pm on 10th March, 2012 #

    Big problem.
    This doesn’t account for clicking again, or clicking on another element. At least it doesn’t when I set it up.

    Trying to work up a solution.

  36. Ramin's Gravatar

    Ramin at 10:42am on 19th March, 2012 #

    I believe a simpler, non-js solution might work as well. Using plain CSS. Just add the following to your css file:

    label { cursor: pointer; }

    That fixed the problem for me. Good luck.

  37. richard's Gravatar

    richard at 3:39am on 16th April, 2012 #

    Works great on your test page, but can’t get it to work in the wild. Pity, I really needed it.

  38. WebsiteInfo's Gravatar

    WebsiteInfo at 9:07pm on 5th May, 2012 #

    In recent days, I am trying to understand it, and searched a lot from the internet.but I still can not find a reasonable one. This article gives a good description about it,and help me understand the issue which confused me a lot.Thanks for your sharing! WebsiteInfo

  39. Sarah's Gravatar

    Sarah at 1:56pm on 12th May, 2012 #

    What a great tips you’ve given about how to fix the broken iPad from label click issue. Thank you I’ll appreciate your knowledge. Thank
    404 error page

  40. Michael Mitschele's Gravatar

    Michael Mitschele at 12:13pm on 15th May, 2012 #

    Both the iPad and iPad 2 are sophisticated pieces of technology, capable of doing great things. It’s also worth noting, however, that they’re both somewhat fragile. If you’re not careful, the glass touch screen can easily be broken, whether it’s dropped, thrown or whether someone happens to take a round of Angry Birds a little too seriously.
    Michael Mitschele

  41. Jeetendra Singh's Gravatar

    Jeetendra Singh at 5:04pm on 6th June, 2012 #

    Thanks a lot for sharing this solution, this save lots of time, thanks again

  42. Tim Acheson's Gravatar

    Tim Acheson at 5:39pm on 8th June, 2012 #

    #iFail

    So much for standards compliance! ;)

  43. Mag Leahy's Gravatar

    Mag Leahy at 5:27pm on 12th June, 2012 #

    Hi there and thanks for your article.
    Ran into this today but whilst looking for a solution I came across this:

    http://stackoverflow.com/questions/4142520/label-not-clickable-in-jqtouch

    “There is an obscure trick for this, using CSS:

    label { cursor: pointer; }

    And it will work on iPhone and iPad.

    Checked this and it works for the iPhone4 at least. Not tested further but it’s better than js.

    Anyone know why this works?

    Rock out techies.
    Mag

  44. swathi P's Gravatar

    swathi P at 5:50am on 26th June, 2012 #

    Thanks a lot for sharing your code.

    It helped me a lot.

  45. Alessandro's Gravatar

    Alessandro at 11:36pm on 28th June, 2012 #

    The best solution is this: add onclick=”” to the label

    <label for=“blah”>blah</label>

  46. Shannon Kusnic's Gravatar

    Shannon Kusnic at 1:30am on 10th November, 2012 #

    Hey there! Someone in my Myspace group shared this website with us so I came to check it out. I’m definitely enjoying the information. I’m book-marking and will be tweeting this to my followers! Exceptional blog and wonderful design and style. Shannon Kusnic