Force Selection of Text Block
Have you ever seen (or put yourself) some text into a or
, not because it was part of a form, but because it made the whole block of text easier to select. Inputs like that have selection boundaries, meaning you can click into them and (for example) Select All and get just the text inside the input.
There is a CSS property that allows us to do that without needing to use a not-particularly-semantically-appropriate form input.
It’s the user-select
property, and it works like this:
.force-select-all {
user-select: all;
}
Autoprefixer will handle this for you, but if doing by hand, this is what you’ll need for the best browser support:
.force-select-all {
-webkit-user-select: all; /* Covers Blink-land & Firefox (yup) */
user-select: all; /* Someday */
}
An example, you ask?
I find the most common use-case for this kind of thing is “here’s some server-generated copy-and-pasteable embed code for Our Thing™”. Imagine the embed code for YouTube or Vimeo videos:
Makes sense on a site like my old HTML-Ipsum, which is in dire need of an update.
A demo
How about a slightly different use-case, a cheat sheet, in which there are some simple code snippets that are intended to be copied:
See the Pen SVG Shape Cheatsheet (user-select: all; demo) by Chris Coyier (@chriscoyier) on CodePen.
More on the prefixing thing
Actually, Autoprefixer will give you:
.force-select-all {
-webkit-user-select: all;
-moz-user-select: all;
-ms-user-select: all;
user-select: all;
}
Which is understandable because:
- It’s weird to just put
-webkit-
for Firefox, even though it takes it - Edge doesn’t support
all
, but it supportsnone
with a prefix, so it always prefixes the property
Let’s say you don’t like the forced selection, but like the selection boundaries.
That’s what the contain value is all about. It makes text selection behave like it would within an input:
.select-text-like-you-would-within-a-textarea {
/* Not supported anywhere yet */
user-select: contain;
}
Alas, no support yet. IE/Edge does support a proprietary version though:
.ie-version-of-contain {
-ms-user-select: element;
}
So now we have none
, all
, and contain
. There is also text
, which makes the text selectable like “normal” text.
If you ever need to reset the value, you should use auto
, as it’s the value that returns the element back to it’s normal state (e.g. a
would return to text, a would return to contain).
Styling selected text
Since we’re talking about selecting text here, remember you can style selected text:
::-moz-selection { background: yellow; }
::selection { background: yellow; }
Although… I might recommend not pairing these, as the auto-selecting text behavior is already a little weird, so that combined with a totally different selection style might be confusing to the point of a person not understanding what is happening.
Or at least, making the ::selection
site-wide, not specific to isolated areas.
The Classic JavaScript Way
No Edge support might be a deal-breaker for you. If it’s mission-critical to auto-select text, you might wanna just stick with an input and JavaScript.
Super basic example:
See the Pen Simplest Select by Chris Coyier (@chriscoyier) on CodePen.
I’m sure you could get a lot fancier, like by avoiding inline event handling, and considering the “OK, I’ve clicked into you and you selected your text, I get it, now stop doing that so I can only select a part of you” – which is certainly possible.
Pseudos
For better or worse, user-select: text;
might be a way to make pseudo elements (like ::before
or ::after
) selectable, which they currently are not in any browser. It’s probably good that you can’t select them, as pseudo elements also aren’t supposed to be read in AT (because they aren’t “content”). But it is kinda strange to see text on a screen you can’t select, so I wouldn’t be surprised whichever way browsers land on this.
Mobile
For iOS, there is yet-another thing you may want to use:
.prevent-touch-callout {
-webkit-touch-callout: none;
}
Not specifically about selection, but if you’re preventing selection of text you’re likely preventing interaction in general. MDN:
When a target is touched and held on iPhone OS, Safari displays a callout information about the link. This property allows disabling that behavior.
Forcing a copy?
Since we’re talking about forcing selection of text, can we force a copy-to-clipboard as well? You can, actually. There used to be a Flash-based way to do it, but, as I think we all know, Flash is pretty dead. Chrome just announced another deathblow. IE 10 supported this execCommand
thing, and as it happens, that seems like the thing that browsers are going with. Snagged this demo from that Google article by Matt Gaunt:
See the Pen Copy Text with a Button (Google Example) by Chris Coyier (@chriscoyier) on CodePen.
Looks like that works in Blink-land, Firefox, and Edge, so… cool.
More information
- user-select on MDN – a bit more detail on here on the prefixes and properetary values.
- Can I Use on support – specifically of the none value
- Current version of spec – the best I can tell
- Document from Google with some interesting specifics on support and links to relevent bugs.
Whew
That was a lot of words for such a simple thing. Good work team.
Force Selection of Text Block is a post from CSS-Tricks