Reveal a Background Image upon Text Selection

Avatar of Chris Coyier
Chris Coyier on (Updated on )

UGURUS offers elite coaching and mentorship for agency owners looking to grow. Start with the free Agency Accelerator today.

We’ve done some fun stuff in the past around these parts with text selection. We made a secret message generator. We made a thing to simulate selecting only a certain number of characters.

In the forums, Aaron Silber wondered about revealing an actual image with text selection. With CSS we know we can change the background color of selected text like this:

::-moz-selection { background-color: #FFA; }
::selection { background-color: #FFA; }

But the actual properties that can be used with these pseudo selectors are very limited1. Background-image is not supported in any browser that supports these text selection pseudo selectors. Aaron made a test page to see exactly what properties are supported with ::selection. Essentially, color and background-color are the only things supported.

So do we give up? Heck no! Turns out there is range object (more about that) in JavaScript which has an API for getting (and to a lesser extent setting) information about the text that is currently selected by the user. With this power, we could figure out what is selected, wrap spans around it and do our styling with those spans (which have no inherit styling limitations). Also turns out the cross browser compatibility for that is not great, but there is an open source project called Rangy for making working with range easier and more cross browser compatible.

A basic demo (from their docs) involves setting a class around selected text after clicking a button:

<script>
    var cssApplier;

    window.onload = function() {
        rangy.init();
        cssApplier = rangy.createCssClassApplier("someClass", true); // true turns on normalization
    });
</script>

<input type="button" value="Toggle someClass on selection" onclick="cssApplier.toggleSelection();">

With that in place, you’ll get a CSS class (“someClass” in above code) to style however you want.

.someClass {
   background-image: url(raptor-attack.png);
}

Obviously, adding a raptor is the best possible idea.

View Demo   Download Files


1 And ::selection has been removed from the spec, so there is no standard for browsers to comply with.