Search code examples
iosiframewebkitfocusmobile-safari

Workaround for iOS 10-12 WebKit (Safari/Chrome) iframe focus bug


I've searched for this specific issue here on StackOverflow and the various Apple/WebKit bug reporting systems but have yet to find it specifically cited (which just doesn't seem possible).

The problem: On our payment page we have various form fields (inputs & selects). For PCI/security purposes we have an iframe that serves the credit card number field (the iframe only has that one field - nothing else).

The issue is that for just iOS users, they sometimes cannot put the focus on the credit card number field. There appears to be 2 different, but related iOS webkit bugs. See the UPDATE below.

If they simply navigate down from one field to another, it usually works. But if they bounce around fields, they can get into the scenario where try-as-they-might they cannot get the focus into the credit card number field it doesn't look like the credit card field gets the focus (appears to be a rendering issue).

Initially we thought maybe there was JS or some invisible DIV getting into the way, but I eventually was able to create an HTML-only example to recreate the problem. (Instructions on how to recreate the issue are on the example page.) Linking to codepen requires I include some code:

<iframe src="iframe.html"></iframe>

I've consistently been able to recreate this issue on iOS 10-12 devices (an iOS 9 device didn't seem to have the problem).

For posterity I'm going to supply the work-around I came across in a separate, but semi-related WebKit bug. However, I was wondering if others out there had stumbled upon this problem and discovered other work-arounds.

UPDATE:

After digging in further I've discovered we're suffering from 2 separate bugs. The first is mostly as I describe above, but seems to be more of a rendering issue where iOS doesn't look like it's putting the focus on a field. However, if you go to the codepen example new example I setup and follow the steps, even when it doesn't look like the field has the focus, if you type the text will render correctly.

The second problem is less likely to happen but is more detrimental. It requires 3 criteria to trip:

  1. The iframe's source has to be cross-origin
  2. Parent page is attaching an event listener to either touchstart, touchmove or touchend (even as simple as an empty function call)
  3. The iframe’s field is off-screen when a different field has focus and the keyboard is present.

The result of these 3 things is that the user cannot place focus on the iframe field at all (typing goes nowhere although document.activeElement shows the last parent page input having focus). Reestablishing the ability to get the focus in the iframe can be difficult, generally need to have a parent page input that can be focused while the iframe field is visible then the user can move their focus to the iframe field from there.

If any of the 3 criteria is changed (not cross-domain, no event listeners on those 3 touch events or the iframe is visible), then only the first – less-prohibitive – bug is present.

I will update my "answer" below with this realization as well.

Update 2: The new example I put up shows both bugs in action; the first page is Bug #1 with a link to the cross-origin Bug #2 example.


Solution

  • Problem is resolved in my environment by adding @Ryan L's suggestion document.addEventListener('touchstart', {}); in the IFrame.

    This is good as it's very simple to add and is specific to the IFrame, not affecting the container page.

    Problem description: cannot 'touch' (select, edit) another form field on Safari running on iDevices (phone & pad) running iOS 12. This only happens on pages in an IFrame where the container page has added some touch events. Very obscure set of conditions that are difficult to debug.