22

The <input> attribute autocapitalize="words" is broken in mobile Safari under iOS 8,9 with the default iOS keyboard. It uppercases the first 2 letters of the field, not the first letter of each word.

Official documentation says is supported: https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariHTMLRef/Articles/Attributes.html

To test, open the following field on iOS emulator or real device:

First name: <input type="text" autocorrect="off" autocapitalize="words" value="First Name">

You can use https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_form_submit to test, or this snippet on iOS 8 or 9:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Test autocapitalize</title>
   </head>
  <body>
    <form>
      <label for="words">autocapitalize="words"</label>
      <input type="text" autocapitalize="words" name="text1" id="words" /><br />
      <label for="sentences">autocapitalize="sentences"</label>
      <input type="text" autocapitalize="sentences" name="text2" id="sentences" /><br />
      <label for="none">autocapitalize="none"</label>
      <input type="text" autocapitalize="none" name="text3" id="none" />
    </form>
  </body>
</html>

I'm amazed this has been present since 8.x and has passed under the radar.

Is there a known workaround?

Update 10/13: iPhone 6s+ Safari completely ignores any HTML attribute set on the input field.

Cameron Little
  • 3,487
  • 23
  • 35
juanca
  • 353
  • 1
  • 9
  • Have you reported this to Apple? – Ken Sep 28 '15 at 14:17
  • Also, I don't see the problem in the w3... url you reference -- could this instead be a problem with JavaScript you are using? – Ken Sep 28 '15 at 18:44
  • 1
    Yes I posted the questions here: https://forums.developer.apple.com/message/57845#57845 Not sure if that's the best place or there might be somewhere else. To clarify on the w3 link that I provided you need to replace the HTML markup with `First name: ` Then you should be able to see the issue – juanca Sep 30 '15 at 05:21
  • I'm not sure the forums are the best place -- I would submit something via the Apple Bug Reporter. More info here: https://developer.apple.com/bug-reporting/ – Ken Sep 30 '15 at 13:24
  • 3
    Bug 22937164 was filed on Apple's bug reporter. Thanks for the reference Ken. – juanca Oct 01 '15 at 18:55
  • 3
    I'm really surprised this isn't a bigger issue but perhaps not a lot of folks are using the "words" option... – Ken Oct 02 '15 at 15:44
  • This still isn't fixed as of May 2016. Any workarounds for this? – ahmd0 May 10 '16 at 00:01
  • From iOS 8 still having this issue in iOS 10. What a heck! – Miguel Peniche Jul 17 '16 at 22:36
  • STill not fixed! SHame on you APple! – Mukul M. Apr 01 '20 at 20:03

1 Answers1

1

There seems to be a workaround for this issue if you are willing to (temporarily) include this library: https://github.com/agrublev/autocapitalize. It does however require jQuery, so might not be ideal on a mobile device. I've created this small piece of code which does the same thing just for words without the use of jQuery. It can ofcourse be extented to also include other cases.

The example below also capitalizes the words initially on page ready, instead of just on the 'keyup' event. I've tested the code on several devices and haven't gotten an error. But feel free to comment if something doesn't work or you feel something can be done better.

Note that the 'domReady' function I added works for IE9 and up. Please see this if you require support for an older version.

// Create one global variable
var lib = {};

(function ( lib ) {

  lib.autocapitalize_element = function (element) {
    var val = element.value.toLowerCase();
    var split_identifier = " ";
    var split = val.split(split_identifier);
    for (var i = 0; i < split.length; i ++) {
      var v = split[i];
      if ( v.length ) {
          split[i] = v.charAt(0).toUpperCase() + v.substring(1);
      }
    };
    val = split.join(split_identifier);
    element.value = val;
  }

  lib.autocapitalize_helper = function(element) {
    element.onkeyup = function(e) {
      var inp = String.fromCharCode(e.keyCode);
      if (/[a-zA-Z0-9-_ ]/.test(inp)) {
        lib.autocapitalize_element(element);
      }
    };
  }

  lib.autocapitalize = function() {
    var elements = document.querySelectorAll("input[autocapitalize], textarea[autocapitalize]");
    for(var i = 0; i < elements.length; i++) {
      lib.autocapitalize_helper(elements[i]);
      lib.autocapitalize_element(elements[i]);
    }
  }

  lib.domReady = function(callback) {
    document.readyState === "interactive" || document.readyState === "complete" ? callback() : document.addEventListener("DOMContentLoaded", callback);
  };
}( lib ));


// This function gets called when the dom is ready. I've added it to the lib variable now because I dislike adding global variables, but you can put it anywhere you like.
lib.domReady(function() {
  lib.autocapitalize();
});
Daan van Hulst
  • 1,426
  • 15
  • 32