Last updated on

Using your cursor select this sentence. Notice how as you select the text a background color fills the space? You can change the background color and color of selected text by styling::selection. Styling this pseudo element is great for matching user-selected text to your site’s color scheme.

p::-moz-selection { color: red}
p::selection { color: red; }

Take note that the double colon is necessary in the syntax for this pseudo element, despite that other pseudo elements accept a single colon.

As seen above, you can style ::selection on individual elements. You can also style the entire page by dropping the bare pseudo element in your stylesheet.

::-moz-selection { background: yellow; }
::selection { background: yellow; }

There are only three properties that ::selection will work with:

  • color
  • background (background-colorbackground-image)
  • text-shadow
<p>Select me to see normal behavior.</p>
<p class='example-color'>Try selecting me for a different text color.</p>
<p class='example-background-color'>You can select me for a different background color.</p>
<p class='example-background'>You can also select me for a different background.</p>
<p class='example-both'>Guess what&hellip; you can select me for a different background color and text color.</p>
<p class='example-shadow'>How about a text-shadow? Sure, select me for a different text-shadow.</p>
<p class='example-background-color'>
  What about nest elements? Select me for a different background color.
  <span class='example-color'>And this sentence is just a color selection.</span>
  Nesting works!
</p>
<input class='example-input' type='text' value='Inputs work!*'>
<textarea class='example-textarea' cols='30' name='' rows='10'>Textarea, too!*</textarea>
<div class='foot-notes'>*not Safari</div>
.example-color::selection {
  color: #8e44ad;
}
.example-background-color::selection {
  background-color: #f1c40f;
}
.example-background::selection {
  background: #e74c3c;
}
.example-both::selection {
  background-color: #8e44ad;
  color: white;
}
.example-shadow::selection {
  text-shadow: 1px 1px 0 #27ae60;
}
.example-input::selection {
  background: #2ecc71;
}
.example-textarea::selection {
  background: #34495e;
  color: white;
}
body {
  font-family: 'Source Sans Pro', Arial, sans-serif;
  line-height: 1.45;
  background: #E0DCCC;
  color: #333;
  padding: 1em;
  font-size: 18px;
}

p,input,textarea  {
  margin-bottom: 1em;
}
input,textarea {
  display: block;
  font-size: 1em;
  font-family: inherit;
}

If you try to style ::selection with a property that’s not on the list, then that property will be ignored. It may be tricky seeing background in that list because the property will only render a color when used on ::selection and it won’t render a background image or gradient.

Also don’t try this:

p::-moz-selection,
p::selection { color: red; }

When browsers find a part of a select they don’t understand, they drop the entire thing, so this will fail all the time.

One of the most helpful uses for ::selection is turning off a text-shadow during selection. A text-shadow can clash with the selection’s background color and make the text difficult to read. Set text-shadow: none; to make text clear and easy to read during selection.

<p>On selection, this text-shadow stays on.</p>
<p class="example">On selection, this text-shadow is set to none.</p>
body {
  font-family: 'Source Sans Pro', Arial, sans-serif;
  line-height: 1.45;
  background: #E0DCCC;
  color: #333;
  padding: 1em;
}
p {
  font-size: 2em;
  font-weight: 900;
  margin-bottom: 1em;
  text-shadow: 1px 2px 1px #C79292;
}

p::selection {
  background: lightblue;
}


.example::selection {
  text-shadow: none;
}

At your own risk

Be advised that ::selection has been removed from the spec. It may not work reliably for all users.

Fancy ::selection

Paired with Sass, or any other preprocessor, you can make really cool effects with::selection. Select the text in the demo below:

HAML

.container
  %h1 Hello world
  %p Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend

SCSS

$selection-bg: #D7624E;
@function shadow($s-color,$s-start,$s-width) {
  $output: '';
  $a: $s-start;
  $x: $a;
  $y: $a;
  $i: 0.0025em;
  $s-size: $s-width + $s-start;
  @while  $x <= ($s-size + $i) {
    $output: $output + '#{$x} #{$y} 0 #{$s-color}';
    @if ($s-size + 0) >=  $x {
      $output: $output + ', ';
    }
    $y: $y + $i;
    $x: $x + $i;
  }
  @return unquote($output);
}

body {
  font-family: 'Source Sans Pro', Arial, sans-serif;
  line-height: 1.45;
  background: #E0DCCC;
  color: #333;
}
.container {
  max-width: 600px;
  margin: 0 auto;
  padding: 1em;
}

h1 {
  font-size: 3.5em;
  font-style: italic;
  text-transform: uppercase;
  letter-spacing: -0.075em;
  margin-bottom: 0.25em;
  line-height: 1.2;
  &::selection { 
    @include text-shadow(shadow( $selection-bg,0,0.1em));
  }
}

p {
  margin-bottom: 1.3em;
  &::selection {
    background: $selection-bg;
    color: white;
  }
}

You might notice the effect is not so smooth in some browsers. Let’s file that demo under: things that are possible, but probably just for fun.

Another dumb-but-fun little trick is revealing an image through selected text.

Browser Support

Chrome Safari Firefox Opera IE Android iOS
Any Any Any 23+ 9+ 4.4+ Nope

Leave a Reply

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