Why does -webkit-user-select:text not work with button in safari?

212 Views Asked by At

This has been bothering me since August '23 when this was first reported, and I can't really find any authoritative answer.

Example: https://jsfiddle.net/1t8Lng2j/

Problem: Text within a <button> element cannot be selected by the user. Safari only (tested with 16/17.x). -webkit-user-select:text doesn't do anything on <button> elements in Safari.

Workaround: Changing to an anchor <a> tag makes text selectable, and anchor tags respond to the css property as expected.

All other browsers behave as expected, and text can be selected within a button element, or the user can be prevented from selecting text if the none property is used.

Does anyone know why -webkit-user-select doesn't work with button elements in safari?

2

There are 2 best solutions below

0
sawacrow On

solution is:

        button:hover, button:active, button:focus, 
    button:focus-visible, button:focus-within{
        -webkit-user-select: text !important;
        pointer-events: none;
    }
    button{
        position: relative;
        line-height: 30px;
    }

problem is: every browser have different default css styles. thats why you see difference for same codes. if you wanna see details open safari and go inpesct, read default styles.

thats some hard case because you working with :hover :active events.

these states are hard for debug.

also: buton is not for text select. if you select right elements, then its be easy. If you're having trouble with something, it's usually the wrong choice.

0
Sam Sabin On

I have a partial answer for you.

-webkit-user-select does work with Safari, it's just that the behavior of -webkit-user-select: text on Safari is different from other browsers.

The default behavior is that if you click and drag within a button on Safari, the text is not selectable. But if you click and drag outside of a button, and continue the drag onto the button, the text is selectable. If -webkit-user-select: is set to none, this behavior no longer works, and the text is not selectable anymore at all, even if you start dragging outside of the element.

I imagine this is a default that Safari has chosen because the desired behavior in most cases is that button text should not be selectable, unless you're trying to copy the contents of the page. To their point, you can find questions of people requesting the exact opposite, who want to know how to turn off selectable text within a button, because they don't want the visual of selected text when the user was just trying to click the button.

I suspect it also has to do with how pointer-events works with buttons on Safari, because if pointer-events is set to none, the button selection works as before, but the entire text gets selected when dragging from outside, instead of the cursor controlling which text to select. This is not the case with the anchor tag, where disabling pointer-events allows the hyperlink to be selected as normal.

Another interesting thing to note is that while anchor tags are selectable as you describe, it is only if there is no href value, unless pointer-events are turned off. If you try and select the text while hovering over the link, it does not select the text, just like the behavior of the button. It may appear at times that this is not the case, as you can select very close outside of the link to drag onto it, but if you add padding, it becomes apparent that the behavior is the same as buttons(except for how pointer-events are handled).

Here is a jsfiddle where you can see some of these concepts in action: jsfiddle

Safari has a unique feature where dragging a link creates a website preview(visible to the user) that is draggable to other applications. Perhaps the default behavior of the text selection being disabled is so that when the preview was shown, it wouldn't have text selected underneath, creating visual confusion for the user.

These are just my speculations, but I think it's important to note that the CSS is not being ignored by Safari, it's just being applied differently.