Rainbow Selection in CSS

Chris Coyier Chris Coyier on

There is a ::selection pseudo class selector in CSS that allows you to style what content (mostly: text) looks like when it’s selected.

Say your website has pretty strong orange-colored branding, you could use this to extend the feel of that branding.

Geoff Grahams website with the first few words of a paragraph selected. The selected text has an orange background color, just like the border of the whole site.

Like:

html {
  --brandColor: orange;
}
::selection {
  background-color: var(--brandColor);
}Code language: CSS (css)

There is really only a couple of things you can set on ::selection (see the allowable properties bit on MDN), which makes sense. You wouldn’t want to be changing font-size on selection or anything like that as it would get messy quickly.

I was on the Lit documentation site the other day and highlighted some text and saw this:

Lit documentation site with 5 paragraphs of text selected, each with slightly different hues of greens and blues as backgrounds.

At first I wasn’t even sure if it was intentional, but I sure thought it was neat! I figured it was just :nth-child() trickery where you hang ::selection off the end of it. Like:

:nth-child(5n)::selection {
  background: oklch(70% 0.111 0 / 72.27%)
}
:nth-child(5n+1)::selection {
  background: oklch(70% 0.111 40 / 72.27%)
}
:nth-child(5n+2)::selection {
  background: oklch(70% 0.111 80 / 72.27%)
}
:nth-child(5n+3)::selection {
  background: oklch(70% 0.111 120 / 72.27%)
}
:nth-child(5n+4)::selection {
  background: oklch(70% 0.111 160 / 72.27%)
}Code language: CSS (css)

So I made a demo of that and it works great:

No dice on iOS but it seems to work everywhere else.

I did ultimately poke at the Lit site with DevTools and saw their approach was basically what I thought it was going to be. Except a little more fancy as they are using color-mix() with their primary colors and setting both the color and background.

If you’re thinking why not go full rainbow like with a linear-gradient() like any sane thinking person is of course, unfortunately gradients are background-images, which are ignored here, with only background-color being supported. 😭🌈

Wanna learn CSS from a course?

Frontend Masters logo

FYI, we have a full CSS learning path with multiple courses depending on how you want to approach it.

7-Day Free Trial

2 responses to “Rainbow Selection in CSS”

  1. Zach Saucier Zach Saucier says:

    So you can kind of do a gradient selection color, but it requires having the text be colored gradient as well…
    https://codepen.io/ZachSaucier/pen/GGXVwd/887e35efea738a2766043a2e3b332631

    I experimented with other hacky ways to get it to be a rainbow but ultimately was not able to come up with a way without coloring the text also

  2. pd says:

    This is NOT ‘neat’, it’s bloated.

    Who wants to download a website with a CSS clause for every paragraph on the off chance users even know how to do multi-select of more than one piece of text?

    The text overhead of all those nth-child() roles may be relatively small on broadband networks but this is also a developer maintenance overhead issue.

    In addition, this is encouraging branding over function. When I get to the point of wanting to copy text, I expect the selection to be consistently system coloured across apps.

    As webdevs, sometimes we enend to take a step back and just stop ourselves from doing things that could annoy the user, just because the CSS intelligentsia allowed us to. Designers and ‘brand’ addicts are notorious for corrupting the user experience by overstepping the line between necessary and sensible. Then we have to tolerate the onslaught of (you really should care more about) accessibility posts to correct the inevitable problems this creates.

Leave a Reply

Your email address will not be published. Required fields are marked *

Did you know?

Frontend Masters Donates to open source projects. $363,806 contributed to date.