5532

For anchors that act like buttons (for example Questions, Tags, Users, etc. which are located on the top of the Stack Overflow page) 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?

Deni J.
  • 1,211
  • 3
  • 21
  • 8
    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? –  Mar 14 '11 at 21:18
  • 8
    Related: http://stackoverflow.com/questions/16600479/how-do-you-override-moz-user-select-none-on-a-child-element = how to allow only some of the child elements to be selected – JK. May 17 '13 at 02:36
  • 10
    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; }` – DaAwesomeP Dec 12 '14 at 01:03
  • 14
    Can I just say: please don't do this. From my experience, I more often than not acctually *want* to select some text that also serves as a button, to copy-paste it somewhere else. It would be unimaginably infuriating not to be able to do that because some web developer went out of their way to purpousely disable this feature for me. So please don't do this unless you have a very, *very* good reason. – kajacx Aug 30 '16 at 20:10
  • 1
    @cram2208 I agree except the other question linked is the duplicate. This question is older and has more/better answers. – www139 Dec 15 '16 at 19:14
  • 3
    In year 2017, it is better way to use `postcss` and `autoprefixer` and set browser version, then `postcss` make everything cool. – AmerllicA Dec 06 '17 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). – Peter Mortensen Nov 24 '19 at 12:23

49 Answers49

7840

UPDATE January, 2017:

According to Can I use, the user-select is currently supported in all browsers except Internet Explorer 9 and its earlier versions (but sadly still needs a vendor prefix).


These are all of the available correct CSS variations:

.noselect {
  -webkit-touch-callout: none; /* iOS Safari */
    -webkit-user-select: none; /* Safari */
     -khtml-user-select: none; /* Konqueror HTML */
       -moz-user-select: none; /* Old versions of Firefox */
        -ms-user-select: none; /* Internet Explorer/Edge */
            user-select: none; /* Non-prefixed version, currently
                                  supported by Chrome, Edge, Opera and Firefox */
}
<p>
  Selectable text.
</p>
<p class="noselect">
  Unselectable text.
</p>

Note that user-select is in standardization process (currently in a W3C working draft). It is not guaranteed to work everywhere and there might be differences in implementation among browsers. Also browsers can drop support for it in the future.


More information can be found in Mozilla Developer Network documentation.

Deni J.
  • 1,211
  • 3
  • 21
Blowsie
  • 38,136
  • 15
  • 81
  • 108
  • 39
    nice code molokoloco :D , although I personally would stay well away from using it, as sometimes you may need the values different for different browsers, and it relys on JavaScript. Making a class and adding it to your element or applying the css to your type of element in your style-sheet is pretty bullet proof. – Blowsie Jan 14 '11 at 13:07
  • 62
    'user-select'- Values: none | text | toggle | element | elements | all | inherit - http://www.w3.org/TR/2000/WD-css3-userint-20000216 – Blowsie Mar 21 '11 at 09:44
  • 329
    this is ridiculous! so many different ways to do the same thing. let's make a new standard for user selects. we will call it `standard-user-select`. then we won't have these problems. although for backwards compatibility we should include the others as well. so now the code becomes `-webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; standard-user-select: none;`. ah, much better. – Claudiu Sep 04 '12 at 16:19
897

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.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Tim Down
  • 292,637
  • 67
  • 429
  • 506
  • 32
    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 '11 at 13:15
  • 70
    @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 '11 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 http://code.google.com/speed/page-speed/docs/rendering.html#UseEfficientCSSSelectors – Blowsie Jan 14 '11 at 13:49
  • 21
    Instead of using the class="unselectable", just use the attribute selector [unselectable="on"] { … } – Chris Calo Jan 26 '12 at 19:39
212

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.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
X-Istence
  • 15,338
  • 6
  • 52
  • 73
  • 22
    The buttons thing would be exactly my motivation. – Kriem May 05 '09 at 20:47
  • This may be necessary for embedded devices. i.e. a device where a browser is used for rendering the UI. – Tim Kersten Nov 04 '09 at 12:05
  • 29
    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. – Gordon Tucker Jan 06 '10 at 16:08
  • 31
    Highly interactive web app with a lot of drag & drop... accidental highlighting is a big usability problem. – Marc Hughes Jun 03 '14 at 21:08
205

A JavaScript solution for Internet Explorer is:

onselectstart="return false;"
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Pekka
  • 418,526
  • 129
  • 929
  • 1,058
146

If you want to disable text selection on everything except on <p> elements, you can do this in CSS (watch out for the -moz-none which allows override in sub-elements, which is allowed in other browsers with none):

* {
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: -moz-none;
    -o-user-select: none;
    user-select: none;
}

p {
    -webkit-user-select: text;
    -khtml-user-select: text;
    -moz-user-select: text;
    -o-user-select: text;
    user-select: text;
}
James Donnelly
  • 117,312
  • 30
  • 193
  • 198
Benjamin Crouzier
  • 34,915
  • 36
  • 154
  • 219
  • 13
    Make sure you also make input fields selectable: `p, input { -webkit-user-select: text; -khtml-user-select: text; -moz-user-select: text; -o-user-select: text; user-select: text; }` – joshuadelange Jul 07 '11 at 22:39
  • 11
    Be very wary about turning off browser UI expectations on ALL code except for one item. What about list items
  • text, for example? – Jason T Featheringham Nov 12 '11 at 07:13
  • Just an update... according to MDN since Firefox 21 `-moz-none` and `none` are the same. – Kevin Fegan Dec 25 '13 at 15:56
  • 2
    For this you may add cursor:default and cursor:text respectively : ) – T4NK3R Jul 14 '14 at 17:14
  • *THE* bomb. That is to say. THE END. ````ul>* { -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: -moz-none; -o-user-select: none; user-select: none; }```` [selects everything in an unordered list, and makes it un-selectable, rather than trashing the whole view tree.] Thanks for the lesson. My button list is looking great, and responding correctly to screen tapping and pressing, rather than launching an IME (android clipboard widgets). – Hypersoft Systems Sep 12 '19 at 06:54
  • great, Ive using this :) – C Alonso C Ortega Mar 16 '20 at 19:07