Using CSS to Control Text Selection / Coder’s Block

nc efi placeholder

CSS lets you control how text selection behaves and appears on your pages. This can help you improve usability in certain situations and add a little bit of visual flair. Let’s dive in!

Select All

Sometimes it’s nice to have all the text in an element automatically selected when you click on it. This is particularly handy for text that is copied/pasted in full (code snippets, one-time passwords, promotional codes, etc.).

You can accomplish this with some simple CSS. No JavaScript required!

div {
    -webkit-user-select: all; 
    user-select: all;
}

Here’s a demo. Bad news, it doesn’t work on iOS. Good news, it degrades gracefully, so the text is still selectable.

See the Pen
Select All
by Will Boyd (@lonekorean)
on CodePen.

Select All… Then Select Some

While this works as expected, you may notice something annoying: it is impossible to select anything less than the entire code snippet. Wouldn’t it be nice if the first click selected all, but you could still click again and select just a portion? CSS can do this.

First, use tabindex to make the element holding the text focusable. This gives the CSS a way to know when the element has been clicked.

<code tabindex="0">code snippet goes herecode>

Then comes the CSS.

code {
    -webkit-user-select: all;
    user-select: all;
}

code:focus {
    animation: select 100ms step-end forwards;
}

@keyframes select {
    to {
        user-select: text;
    }
}

The idea is to have user-select: all on the element initially, then switch to the “normal” user-select: text after the element has focus so that text can be freely re-selected. The tricky part is the timing. Do the switch immediately upon focus and user-select: all is gone before it has a chance to do its job. That’s where animation comes in.

Yes, user-select is animatable! More specifically, it is discretely animatable, meaning there is no gradual interpolated animation, but rather an immediate cut from one state to another. Armed with this knowledge, we can use animation to delay the change in select behavior until 100ms after focus. Perfect.

Again, the “select all” bit doesn’t work on iOS. Meanwhile, desktop Safari keeps the text as “select all”. This trick seems to work fine elsewhere, though.

See the Pen
Select All… Then Select Some
by Will Boyd (@lonekorean)
on CodePen.

Preventing Text Selection

You can also use CSS to make text in an element unselectable.

label {
    -webkit-user-select: none;
    user-select: none;
}

This is probably a bad idea for body text, but I’ve found it useful for controls that might be toggled quickly or “rage clicked” in desktop browsers, since double clicking causes text to be selected and highlighted, which can look a little weird sometimes.

See for yourself in the following demo. Notice how the toggle on the left becomes highlighted when rapidly clicked, while the one on the right doesn’t.

See the Pen
Preventing Text Highlights from Rage Clicking
by Will Boyd (@lonekorean)
on CodePen.

This technique also works on disclosure widgets. Fake buttons — like a

with a click handler on it — are another candidate. Bear in mind that using a real