Using CSS, it’s possible to prevent users from selecting text within an element using
user-select: none. Now, it’s understandable why doing so might be considered “controversial”. I mean, should we be disabling standard user behaviors? Generally speaking, no, we shouldn’t be doing that. But does disabling text selection have some legitimate (albeit rare) use-cases? I think so.
In this article we’ll explore these use cases and take a look at how we can use
user-select: none to improve (not hinder) user experiences. It’s also worth nothing that the
user-select property has other values besides
none that can be used to alter the behavior of text selection rather than disable it completely, and another value that even enforces text selection, so we’ll also take a look at those.
Let’s kick things off by running through the different
user-select values and what they do.
user-select: none; to an element means that its text content and nested text content won’t be functionally selectable or visually selectable (i.e.
::selection won’t work). If you were to make a selection that contained some non-selectable content, the non-selectable content would be omitted from the selection, so it’s fairly well implemented. And the support is great.
Mobile / Tablet
|Android Chrome||Android Firefox||Android||iOS Safari|
user-select: text makes the content selectable. You’d use this value to overwrite
user-select: contain is an interesting one. Applying it means that if a selection begins within the element then it must end within it too, containing it. This oddly doesn’t apply when the selection begins before the element, however, which is probably why no browser currently supports it. (Internet Explorer and earlier versions of Microsoft Edge previously supported it under the guise of
user-select: all, selecting part of the element’s content results in all of it being selected automatically. It’s all or nothing, which is very uncompromising but useful in circumstances where users are more likely to copy content to their clipboard (e.g. sharing and embedding links, code snippets, etc.). Instead of double-clicking, users will only need to click once for the content to auto-select.
A better application of
user-select: all is to ensure that quotes are copied entirely and accurately.
The behavior of
user-select: auto (the initial value of
user-select) depends on the element and how it’s used. You can find out more about this in our almanac.
Now let’s turn to exploring use cases for
Stripping non-text from the selection
When you’re copying content from a web page, it’s probably from an article or some other type of long-form content, right? You probably don’t want your selection to include images, emoji (which can sometimes copy as text, e.g. “:thinkingface:”), and other things that you might expect to find wrapped in an