Categories
cross-browser css highlight textselection

How to disable text selection highlighting

5872

For anchors that act like buttons (for example, the buttons on the sidebar of this Stack Overflow page titled Questions, Tags, and Users) or tabs, is there a CSS standard way to disable the highlighting effect if the user accidentally selects the text?

I realize that this could be done with JavaScript and a little googling yielded the Mozilla-only -moz-user-select option.

Is there a standard-compliant way to accomplish this with CSS, and if not, what is the “best practice” approach?

5

  • 9

    can elements within the element witch has highlighting disabled, have highlighting enabled with in css in the style or class attribute? or in other words, are there other values for -webkit-user-select ect. other than just none?

    – user659576

    Mar 14, 2011 at 21:18

  • 8

    Related: stackoverflow.com/questions/16600479/… = how to allow only some of the child elements to be selected

    – JK.

    May 17, 2013 at 2:36


  • 11

    There a bug in some browsers where doing “Select All” (CTRL+A and CMD+A) still selects things. This can be fought with a transparent selection color: ::selection { background: transparent; } ::-moz-selection { background: transparent; }

    Dec 12, 2014 at 1:03


  • 3

    In year 2017, it is better way to use postcss and autoprefixer and set browser version, then postcss make everything cool.

    – AmerllicA

    Dec 6, 2017 at 11:47

  • 1

    The user interface changed. In 2019, all three mentioned items are now in a hamburger menu in the upper left. “Tags” and “Users” are in there, and “Questions” is now called “Stack Overflow” (with an icon in front).

    Nov 24, 2019 at 12:23


931

+50

In most browsers, this can be achieved using proprietary variations on the CSS user-select property, originally proposed and then abandoned in CSS 3 and now proposed in CSS UI Level 4:

*.unselectable {
   -moz-user-select: none;
   -khtml-user-select: none;
   -webkit-user-select: none;

   /*
     Introduced in Internet Explorer 10.
     See http://ie.microsoft.com/testdrive/HTML5/msUserSelect/
   */
   -ms-user-select: none;
   user-select: none;
}

For Internet Explorer < 10 and Opera < 15, you will need to use the unselectable attribute of the element you wish to be unselectable. You can set this using an attribute in HTML:

<div id="foo" unselectable="on" class="unselectable">...</div>

Sadly this property isn’t inherited, meaning you have to put an attribute in the start tag of every element inside the <div>. If this is a problem, you could instead use JavaScript to do this recursively for an element’s descendants:

function makeUnselectable(node) {
    if (node.nodeType == 1) {
        node.setAttribute("unselectable", "on");
    }
    var child = node.firstChild;
    while (child) {
        makeUnselectable(child);
        child = child.nextSibling;
    }
}

makeUnselectable(document.getElementById("foo"));

Update 30 April 2014: This tree traversal needs to be rerun whenever a new element is added to the tree, but it seems from a comment by @Han that it is possible to avoid this by adding a mousedown event handler that sets unselectable on the target of the event. See http://jsbin.com/yagekiji/1 for details.


This still doesn’t cover all possibilities. While it is impossible to initiate selections in unselectable elements, in some browsers (Internet Explorer and Firefox, for example) it’s still impossible to prevent selections that start before and end after the unselectable element without making the whole document unselectable.

4

  • 34

    you should remove the * selector from your example, its really in-efficient and there really isnt any need to use it in your example is there?

    – Blowsie

    Jan 14, 2011 at 13:15

  • 71

    @Blowsie: I don’t think so: the CSS 2 spec states that *.foo and .foo are precisely equivalent (in the second case, the universal selector (*) is implied), so barring browser quirks, I can’t see that including the * will harm performance. It’s a long-standing habit of mine to include the *, which I originally started doing for readability: it explicitly states at a glance that the author intends to match all elements.

    – Tim Down

    Jan 14, 2011 at 13:24


  • 40

    oooh after some further reading, it seems * is only un-effiecient when using it as the key (the righmost selector) ie .unselectable * . Further info here code.google.com/speed/page-speed/docs/…

    – Blowsie

    Jan 14, 2011 at 13:49


  • 21

    Instead of using the class=”unselectable”, just use the attribute selector [unselectable=”on”] { … }

    Jan 26, 2012 at 19:39

227

Until CSS 3’s user-select property becomes available, Gecko-based browsers support the -moz-user-select property you already found. WebKit and Blink-based browsers support the -webkit-user-select property.

This of course is not supported in browsers that do not use the Gecko rendering engine.

There is no “standards” compliant quick-and-easy way to do it; using JavaScript is an option.

The real question is, why do you want users to not be able to highlight and presumably copy and paste certain elements? I have not come across a single time that I wanted to not let users highlight a certain portion of my website. Several of my friends, after spending many hours reading and writing code will use the highlight feature as a way to remember where on the page they were, or providing a marker so that their eyes know where to look next.

The only place I could see this being useful is if you have buttons for forms that should not be copy and pasted if a user copy and pasted the website.

3

  • This may be necessary for embedded devices. i.e. a device where a browser is used for rendering the UI.

    Nov 4, 2009 at 12:05

  • 32

    Another reason this is needed is Shift-clicking to select multiple rows in a grid or table. You don’t want to to highlight the text, you want it to select the rows.

    Jan 6, 2010 at 16:08

  • 34

    Highly interactive web app with a lot of drag & drop… accidental highlighting is a big usability problem.

    Jun 3, 2014 at 21:08