Do you want to request a feature or report a bug?
Bug
What is the current behavior?
In mobile safari and some versions of desktop safari onClick on any non-anchor element requires two click to trigger if
display: inlinedisplay: flex (thanks @malash)It can be worked around by either
onClick and then having multiple text nodes within that instead, e.g. <span onClick={thing}><span>multi{' '}nodes</span></span> instead of <span onClick={thing}>multi{' '}nodes</span>If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://jsfiddle.net or similar (template: https://jsfiddle.net/84v837e9/).
This can be seen on this fiddle - https://jsfiddle.net/y8Lh8937/
Note that you'll need to zoom in to make sure you're hitting the "Nah" on mobile to reproduce the behaviour, as it's sensitive to the exact area hit.
Note that on desktop, to ensure that you're clicking on the text, you should be seeing the text cursor when over the "Nah" items; if you're seeing the default cursor then you're on the <span> (which will work).
What is the expected behavior?
All text nodes should trigger the click handler on the first click.
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
Current react
Desktop Safari 10.1.1 (12603.2.4)
Mobile Safari on iOS 10.3.2 (14F89) (use agent 5.0 (iPhone; CPU iPhone OS 10_3_2 like Max OS X) AppleWebKit/603.2.4 (KHTML, like Gecko) Version/10.0 Mobile/14F89 Safari/602.1)
Thanks to @scottlyttle and @stella-h for this.
Huh. So it does. _Very interesting_. I _think_ this could be because there is a stub onclick handler for interactive elements (like buttons and links) to work around an issue where iOS Safari does not bubble click events:
Thanks for the great write up! I want to incorporate this test case into our manual DOM test fixtures. From there, maybe we can identify when this started happening.
I meet the same problem when using flex: https://jsfiddle.net/malash/LpLxjsqe/6/.
Thanks @malash, updated the issue description to indicate that display: flex also triggers it and doesn't require the padding to do so.
Credit to @scottlyttle and @stella-h for tracking this down, I just did the write up.
A temporary fix:
react-issue-10116-fix.jsx
import React from 'react';
import style from './react-issue-10116-fix.css';
export const getComponent = Component => ({ children, ...rest }) => (
<button
className={style.button}
>
<Component {...rest}>
{children}
</Component>
</button>
)
export const Span = getComponent('span');
// more tags
react-issue-10116-fix.css
.button {
padding: 0 !important;
margin: 0 !important;
border: 0 !important;
border-radius: 0 !important;
background: transparent !important;
color: inherit !important;
font: inherit !important;
line-height: normal !important;
overflow: visible !important;
user-select: none !important;
}
Usage
import { Span } from './path/to/react-issue-10116-fix';
<Span>Hello{', '}world</Span>
// instead of
// <span>Hello{', '}world</span>
Thanks, our use cases were simple enough that we could always just build up the content inside through string templates instead (although it's a little less readable), so we've been able to work around it that way (second of my suggested workarounds in the initial writeup), but that may be useful for others.
I think this is related to a known webkit bug, described on MDN (MDN provides others pointers about this behavior).
@ghostd that's what we initially thought too, but the problem affects non-mobile safari as well, and most workarounds suggested didn't work (e.g. cursor pointer, adding onclick). IIRC using an <a> _and_ specifying a dummy onClick on the element did work as a workaround did work (@scottlyttle or @stella-h may recall exactly).
Unreal. For me, this is most easy to see/test in Desktop Safari 10.1.1 (thanks @elyobo).
I made a test case outside of React using the same generated markup:
https://codepen.io/nhunzaker/pen/LLoRaX
This... is a very hard bug. It's possible that this is related to how React wraps text content with comments:
<span id="target">
<!-- react-text: 6 -->Yea,<!-- /react-text -->
<!-- react-text: 7 -->*******<!-- /react-text -->
<!-- react-text: 8 -->Nah<!-- /react-text -->
</span>
But that exhausts my knowledge of the problem. This feels like a browser bug that we've stumbled into because of the change made to handle text nodes with comments instead of spans.
I'm unable to reproduce this in Desktop Safari version 10.1.2 on macOS 10.12.6. Maybe the patch release fixed it?
@nhunzaker I think it's likely that the comments are related to the problem. This issue does not occur with React 16, which doesn't wrap text in comments.
Here's a version of the original JSFiddle running the React 16 RC: https://jsfiddle.net/z830gyrj/
I verified on iOS 10.3 that the issue does not occur anymore. Since it's likely a browser bug, I think it's safe to just say that this will be resolved in React 16, since including a fix in a 15.x release is unlikely.
@aweary Sorry to get back to this so late. This sounds good. I don't know of any non-trivial way to fix this in a patch to 15, and it's awesome that Safari might have fixed it.
React 16 doesn't wrap text in comments? 馃帀馃帀馃帀 All around.
More 馃帀馃帀馃帀
Good outcome, thanks all.
Most helpful comment
@aweary Sorry to get back to this so late. This sounds good. I don't know of any non-trivial way to fix this in a patch to 15, and it's awesome that Safari might have fixed it.
React 16 doesn't wrap text in comments? 馃帀馃帀馃帀 All around.
More 馃帀馃帀馃帀