How to disable text selection highlighting?

4 501

1 187

For anchors that act like buttons (for example, Questions, Tags, Users, etc. at 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 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?

anon

Posted 2009-05-05T20:29:18.237

Reputation:

6

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. – 2013-05-17T02:36:13.753

8There 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 – 2014-12-12T01:03:56.140

7can 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? – None – 2011-03-14T21:18:15.803

176

'user-select'- Values: none | text | toggle | element | elements | all | inherit - http://www.w3.org/TR/2000/WD-css3-userint-20000216

– Blowsie – 2011-03-21T09:44:59.017

4Can 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 – 2016-08-30T20:10:51.440

1@cram2208 I agree except the other question linked is the duplicate. This question is older and has more/better answers. – www139 – 2016-12-15T19:14:23.320

1In year 2017, it is better way to use postcss and autoprefixer and set browser version, then postcss make everything cool. – AmerllicA – 2017-12-06T11:47:05.790

Answers

6 563

UPDATE January, 2017:

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


All of the correct CSS variations are:

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

Note that it's a non-standard feature (i.e. not a part of any specification). It is not guaranteed to work everywhere, and there might be differences in implementation among browsers and in the future browsers can drop support for it.


More information can be found in Mozilla Developer Network documentation.

Blowsie

Posted 2009-05-05T20:29:18.237

Reputation: 33 925

29For some reason, this alone wasnt working in IE8, I then added &lt;div onselectstart="return false;"&gt; to my main div. – robasta – 2012-01-20T08:11:49.997

Doesn't work for mobile? Android stock browser still selects text (when touch holding) with all this CSS attached. (Desktop browser doesn't (double click or drag).) On mobile the only way to disable text selection seems to be capturing touchstart, but that disables the entire click event for that element. Ideas? – Rudie – 2012-04-06T11:10:25.070

This works on some versions of android but not all. Out of curiosity, which version of Android are you referring to? – Blowsie – 2012-04-10T07:41:24.580

2-moz-user-select should be set to -moz-none or you cannot reset user selection on child elements in firefox. – Andre Backlund – 2012-04-19T16:46:48.300

@think123: It isn't really as cross-browser as you can get: it doesn't help you in Opera or IE < 10, both of which do provide alternative ways of making content unselectable. – Tim Down – 2012-08-03T16:55:57.853

276this 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 – 2012-09-04T16:19:11.420

18The debate of browser specific prefixes has been on going for ages. Here is not really the correct place to discuss it. Also why would you bother calling it standard-user-select when you can just call it user-select. For now the best way to get round these differences is building mixins in less or sass or similar. – Blowsie – 2012-09-05T08:21:24.543

8

@Claudiu: The reason the prefixed versions have not converged on a standard user-select property is that user-select appeared in an early CSS 3 draft but was later removed, presumably because it was considered to be more concerned with behaviour than styling and hence outside the scope of CSS.

– Tim Down – 2012-09-19T10:54:12.883

@rob's answer turned out to be the ticket for me. All the CSS (which we already had) did zip in IE8. – podperson – 2012-10-04T15:51:50.367

@podperson: There is a non-CSS and non-JavaScript option in IE 8, which is the unselectable attribute. – Tim Down – 2012-10-06T23:00:52.463

It's not working in Opera 12.02 though. – Slava Fomin II – 2012-10-12T13:46:36.440

@SlavaFominII: What isn't working in Opera 12.02? – Tim Down – 2012-10-15T21:37:55.193

@TimDown i can't get the expected results with styles specified in this answer in my Opera 12.02 on XUbuntu-box and i think it worth mentioning. – Slava Fomin II – 2012-10-16T01:39:18.570

2@SlavaFominII: Right. Yes, Opera does not implement a proprietary user-select CSS property. – Tim Down – 2012-10-16T08:24:36.087

This is great and prevents all mouse highlighting, though if I do "Edit->Select All" it still highlights. – Primus202 – 2013-03-15T22:15:37.193

&lt;SHIFT&gt; + &lt;LMB&gt; or &lt;CTRL&gt; + &lt;SHIFT&gt; + &lt;LMB&gt; in IE10 will select everything even if you click inside an element with this style. Not on Chrome or Firefox though. I found that putting the style on the BODY element solved the problem. But this of course disables selection on the entire page, which could be a problem in some cases. – Bjørn Stenfeldt – 2013-04-17T13:56:15.527

1@BjornStenfeldt Actually, just highlighting and selecting as normal will select anything in IE 10 with the above CSS (and 9 for that matter). I have to -1 this answer (like it matters) because I came here so I could replace the deprecated "unselectable" attribute, but alas, I cannot (the red squiggly line remains, and my eye-twitch continues). His CSS works great for all browsers except IE (which means he has either not included a rule or no such rule exists for IE 9 & 10 [not sure about 8 and below]). Either way, he should have said something about this in his answer. – VoidKing – 2013-04-19T15:55:37.590

@blowsie I guess 1,318 viewers (at the time of this writing) don't have clients that will use IE... As satisfying as I find that assumption, I also find it hard to believe. Great job on the other CSS rules, though. It was good of you to include -webkit-touch-callout: none;. I wouldn't have thought of that. – VoidKing – 2013-04-19T16:06:38.040

@Blowsie One more thing: what's the point in including -ms-user-select: none;? Doesn't "ms" stand for Microsoft? Maybe this rule targets IE 8 and below? – VoidKing – 2013-04-19T16:07:46.950

@VoidKing Using the -ms browser prefix actually does work for IE 10, and not for IE 8. Not sure about IE 9. – Pluto – 2013-06-03T17:17:23.230

2I'd suggest adding cursor:default; to not indicate selectibility to the user – Julian F. Weinert – 2013-06-16T22:28:45.507

@Julian, its not quite as simple as that, what if the element is a link or contains links? – Blowsie – 2013-06-17T07:37:45.880

Use prefixfree.js, so you can leave out all the prefixes! – Anselm – 2013-06-23T12:01:09.047

4

That -moz-user-select: moz-none; rule doesn't work in latest Firefox 22, please fix it with the correct value: -moz-user-select: none; (used it here: http://jsfiddle.net/jdNa9/3/ ) Thank you.

– Stano – 2013-08-03T18:22:59.723

Sass/Compass mixin makes this easy. http://bit.ly/1gBasVh – bergie3000 – 2014-02-14T00:00:01.360

In IE 11, if you click at the beginning of "Unselectable text", press shift, and then click at the end of it, then the text becomes selected. – Claudix – 2014-10-07T10:31:06.030

1Internet Explorer has a bug with this CSS code. If you start selection from the Selectable text and continue to drag down, then you can select the unselectable text. – Samy S.Rathore – 2015-02-16T07:53:34.990

@Blowsie Why is -khtml-user-select necessary? Does Konqueror actually support it? I can't seem to find any documentation on it, but then I've never used Konqueror. – Toothbrush – 2015-08-02T18:42:35.503

@toothbrush Its for old versions of Safari (less than 2.0) – Blowsie – 2015-08-04T07:35:33.273

2

As mentioned in one of the previous comments - "How standards proliferate" - https://xkcd.com/927/

– Mars Robertson – 2015-08-04T14:36:40.657

@Blowsie Wow, Safari < 2.0... Never thought of that! So, I don't need to include it for compatibility, unless I need to support every possible browser? – Toothbrush – 2015-08-05T12:48:35.643

6

I have made a function to autodetect CSS prefix ;) http://www.b2bweb.fr/molokoloco/js-cssprefix/

– molokoloco – 2011-01-14T12:13:00.173

34nice 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 – 2011-01-14T13:07:07.943

I can select the unselectable text in the example you provided in (IE 11, Windows 8.1) on touchscreen laptop by double tapping the text. Is there a way to prevent this behavior? – ChocolateAndCheese – 2015-09-01T22:30:45.207

51

'user-select'- Values: none | text | toggle | element | elements | all | inherit - http://www.w3.org/TR/2000/WD-css3-userint-20000216

– Blowsie – 2011-03-21T09:44:40.967

This can be avoided. – NoOneIsHere – 2016-06-20T17:24:06.230

1user-select: none; seems to work in Chrome now. Good enough for me. – Elad Nava – 2016-12-01T13:55:17.223

Pathetic. This kind of feature has been available in Flash since AS1 for nearly two decades. http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/text/TextField.html#selectable So much for standards.

– Triynko – 2017-01-30T19:28:04.913

Everywhere I read says user-select: none is supported in the latest Firefox (Feb 2017), but it's not. The dev tools cross it out with the message "invalid property value". I still need to use -moz-user-select: none to get no-selection working. – BlueRaja - Danny Pflughoeft – 2017-02-06T18:14:25.110

33Actually -o-user-select isn't implemented in Opera. It implements IE's unselectable attribute instead. – Tim Down – 2011-07-03T10:52:17.557

Great answer! Do you know if there is a way to override this a child of an element with this style? I've tried x:text !important; x:auto !important; and x:normal !important; to no avail. – Gary – 2011-07-11T18:19:54.140

Could you maybe add whether using body { /* ..., etc */ user-select: none; } would work well. Or html { /* ..., etc */ user-select: none; } – 太極者無極而生 – 2017-12-14T04:55:16.153

@Fantabulum Children inherit these styles automatically:) – Morteza Milani – 2011-08-18T08:06:21.483

@Morteza: That is correct, the problem is breaking that inheritance... – Gary – 2011-08-18T13:54:09.030

sorry! then try to set inherits:none in children. I'm not sure it works or not. but it should. – Morteza Milani – 2011-08-18T15:28:11.763

This doesn't work with a contenteditable div. – mbomb007 – 2018-03-21T16:14:46.607

@Claudiu The reason for vendor prefixes is that they may have differences in implementation. In the case of user-select, e.g. the inheritance of absolutely positioned elements is implemented inconsistently. But I agree that careful usage of a wildcard to target all prefixes could've been useful for code readability. – Yeti – 2018-09-19T09:42:13.067

@codespy rolling back since the question asks for a valid css solution – Blowsie – 2018-10-31T15:03:35.157

760

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

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

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

For IE < 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 re-run 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 (IE 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.

Tim Down

Posted 2009-05-05T20:29:18.237

Reputation: 246 603

18Instead of using the class="unselectable", just use the attribute selector [unselectable="on"] { … } – Chris Calo – 2012-01-26T19:39:16.870

1@ChristopherJamesCalo: Yes, that is an option. I've resisted it because adding the unselectable attribute invalidates your HTML and the attribute selector won't work with nodes made unselectable via the unselectable property in JavaScript. – Tim Down – 2012-01-26T23:17:20.317

2Please remove the * selector. – Francisc – 2012-04-24T20:02:31.570

.className gets all elements of a given class name. Adding the * selector will tell it to search for that class name again in all DOM elements on the page. It's necessary and slow. – Francisc – 2012-04-25T08:35:34.507

12@Francisc: No. As I said to Blowsie earlier in the comments, it makes precisely no difference. – Tim Down – 2012-04-25T09:32:26.227

1Browsers parse CSS from right to left. If they are clever enough to ignore *.className, great, but why rely on that? You can't know. It's extra specificity and redundant. I see no difference between what you did and html body .className which again is not needed. If you want to increase specificity for this particular case (not everytime) just use !important because you will always want elements with that class to not be selectable. – Francisc – 2012-04-25T17:22:30.657

4@Francisc: It isn't any more or less specific. Read the spec: the * is implied if omitted. I explained my reasoning for including it earlier in the comments, which is that I have found it useful in the past to remind myself explicitly that I'm intending matching all elements. I'm certainly not saying everyone should do it. Equally, it's doing no active harm. – Tim Down – 2012-04-25T17:42:16.560

You're right, the * selector has no specificity, I was wrong. I'm still not convinced that browsers don't parse elements twice though. – Francisc – 2012-04-25T20:32:08.600

1@Francisc: I'd be very surprised if they did. I would expect any difference to disappear at the selector parsing stage rather than the matching stage. – Tim Down – 2012-04-25T23:17:12.390

2@beanland: Turns out you were right: in standards mode only, you need to use setAttribute("unselectable", "on") in IE 9. I've updated my answer. – Tim Down – 2012-07-22T16:04:22.907

@Francisc: I don't believe RTL parsing applies when evaluating simple selectors in a simple selector sequence. It just doesn't make any sense. Even if browsers do somehow parse *.className twice, then .className would have to be double-parsed as well in order to match the spec (the implied * would have to search all elements as well). Then you get the same hypothetical performance hit, which defeats the purpose of removing the * in the first place. What's the point?

– BoltClock – 2012-08-05T16:50:26.460

If browsers do RTL parsing for every kind of rule, there would be a difference. With * it would look for all elements .className, then again filter elements that match * which also have that class. Without the *, it would just look for all elements with .className. But again, I don't know if (all) browsers are clever enough not to double-parse the same elements in the case of *.className. – Francisc – 2012-08-07T21:48:42.937

1@Francisc: I'd be extremely surprised if any browser acted on the .className part of x.className without parsing x as well. Without parsing the whole selector it can have no idea of the context of the class selector and it would be obviously extremely inefficient to search the whole document unnecessarily. – Tim Down – 2012-08-07T22:32:59.680

3An element will always match * without question. Attempting to match it is only going to waste a browser's time whether it is there or not, so the choice of placing it there is essentially purely stylistic and up to the author's taste. For that matter, what's the point of debating all this anyway? – BoltClock – 2012-08-21T08:24:03.193

4Can you elaborate on "proposed-but-now-defunct"? – Kos – 2012-10-10T16:26:38.077

3

@Kos: The link is to an ancient draft from 2000 of a proposal for part of CSS 3, "User Interface for CSS3". I believe that spec was superseded by the CSS3 UI spec, which makes no mention of user-select. I imagine there are mailing list archives containing discussions about its removal somewhere on the web, but I haven't been able to find them.

– Tim Down – 2012-10-10T17:31:49.287

@TimDown @Francisc I think what he's talking about is * .className instead of *.className. The first one could be slow, depending on the implementation because it means match all elements and for each element, look for all instances of the class regardless of tag name. The second implementation means look for all instances of this class regardless of the tag name which is equivalent to .className. If the implementation is smart enough the difference should be negligible. A worse case is it passes through the whole document twice, the first pass being useless. – Mel – 2013-06-14T10:25:14.300

@TimDown: turns out that instead of a full-fledged tree-traversal that won't work if any descendant elements are inserted subsequently, you can just set unselectable on the event.target of mousedown: http://jsbin.com/yagekiji/1

– Han Seoul-Oh – 2014-04-30T19:38:40.800

@Han: Great research. You need a bit of extra code for people not using jQuery, since target and preventDefault() are not supported for events in IE <= 8. I've added a note to my answer, I hope you don't mind. – Tim Down – 2014-04-30T23:12:54.193

@TimDown Not at all, that's everything what I was hoping for. Didn't know about .srcElement/.returnValue, I guess I've had a sheltered childhood thanks to jQuery, TIL! – Han Seoul-Oh – 2014-05-15T20:13:53.753

27you 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 – 2011-01-14T13:15:46.777

62@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 – 2011-01-14T13:24:43.410

34

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 – 2011-01-14T13:49:02.980

3The unselectable attribute does not seem to be working in IE 9 – Ian Hunter – 2011-07-27T21:41:43.437

@beanland: I can't test this right now, but I'd be surprised if this were the case. – Tim Down – 2011-07-27T22:42:38.970

2@beanland: I've tested the unselectable attribute in IE 9 now and it works fine. – Tim Down – 2011-09-06T14:27:20.583

170

A JavaScript solution for IE is

onselectstart="return false;"

Pekka 웃

Posted 2009-05-05T20:29:18.237

Reputation: 353 518

8one more thing here. If you add that to the body then you won't be able to select text inside textareas or input fields in IE. The way I fixed it for IE . body.onselectstart = function(e) { if (e.target.nodeName != "INPUT" &amp;&amp; e.target.nodeName != "TEXTAREA") { e.preventDefault(); return false; } return true; } – TheBrain – 2013-05-30T16:56:05.333

2This can be added as an attribute using jQuery - $("p").attr("onselectstart","return false")

This was the only reliable method for me in IE8 – Matt – 2013-06-05T15:06:46.643

5why I have use javascript when I have multi css solutions!.. – Abudayah – 2013-10-31T10:43:03.980

11@Abudayah because they don't work in older versions of Internet Explorer? That's, like, the entire point of this answer. – Pekka 웃 – 2013-10-31T13:27:22.857

47Don’t forget about ondragstart! – Mathias Bynens – 2010-05-26T13:25:39.027

167

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.

X-Istence

Posted 2009-05-05T20:29:18.237

Reputation: 12 677

This may be necessary for embedded devices. i.e. a device where a browser is used for rendering the UI. – Tim Kersten – 2009-11-04T12:05:52.850

Being able to [ctrl-a], [ctrl-c] only the text content portion of a site would be useful imo. – codeinthehole – 2009-11-13T16:19:08.110

@CraigM If you want to make text unselectable, use an image library such as csImageFile to create images from the text. Users can still print, but will not be able to get the original text without typing it or performing OCR. – ErikE – 2012-11-21T19:09:04.843

23Another 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 – 2010-01-06T16:08:11.053

1We have a product that delivers exams to end users electronically, and our publishers want to take as many measures as possible to prevent users from easily copying & pasting their content. – Kyle Fox – 2010-04-29T21:37:23.370

1Creating Cookie-Clicker-type game in browser is my motivation why I would like to disable text selection. – Dread Boy – 2013-12-25T19:30:53.550

5@CraigM The css style doesn't stop a person from grabbing the HTML source and copying it. If you want to protect your content you'll have to find better ways. – Agile Jedi – 2013-12-26T23:25:50.723

@AgileJedi - Obviously. My comment was addressing the question of why someone would want to disable text selection in the first place. The contractual requirement I mentioned recognized that html source cannot be protected, but required in browser text selection to be disabled. In any case, I've long since moved on from that contract. – Craig M – 2013-12-27T17:47:46.523

Some users have a habit of clicking several times on text which selects not only the text they're after but buttons around it too or other undesirables- eg an entire input field control (not just the content). If you consider an applcation delivered via web browser (as opposed to just a website on the interner), disabling select where it's not desirable would be pretty handy. Shame it's such a faff. – user2808054 – 2014-04-02T14:23:02.300

2What if you are trying to make a touch compatible web app and you don't want the user to accidently engage the click-drag feature? – AnjoMan – 2014-04-29T18:12:04.877

If I have a couple of elements in the background of a page, it would help if they couldn't be selected. – starbeamrainbowlabs – 2014-05-30T17:34:30.883

22Highly interactive web app with a lot of drag & drop... accidental highlighting is a big usability problem. – Marc Hughes – 2014-06-03T21:08:07.717

7There are also legal issues where someone else's content is being legally republished but a clause in the license requires web publishers to prevent text from being easily copied and pasted. This is what led me to find this question. I don't agree with the requirement but the company I'm contracting for is legally obligated to implement it this way. – Craig M – 2011-03-15T20:34:20.267

17The buttons thing would be exactly my motivation. – Kriem – 2009-05-05T20:47:17.617

1

In my case, this will be an application running in a browser on with a touchscreen monitor. There will be no keyboard interface, only touch. Buttons that have text in them can become inadvertently selected by touching the same button repeatedly. And, as the spec says "None of the element's content can be selected. This is a very important value of user-select for user interface elements in particular. This value is one of the aspects of how a button behaves. The user cannot select any of the content inside the button. "

– Scott Marcus – 2017-08-18T15:49:44.090

1"The real question is, why do you want users to not be able to highlight and presumably copy and paste certain elements?" God seriously, wtf do you care? I hate answers that include stuff like this. Thanks for your drawn out answer including your opinions on practical application for text highlighting, but it is irrelevant to the question and I am sure the OP cares less about what you like and is trying to make something his own. Can it be done? Yes? Answer how and be done. No? Answer no and be done. – JSON – 2018-04-28T16:52:52.470

Many sites dont allow you to copy because of copyright reasons – carkod – 2018-09-19T13:32:19.797

124

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;
}

Benjamin Crouzier

Posted 2009-05-05T20:29:18.237

Reputation: 22 904

Just an update... according to MDN since Firefox 21 -moz-none and none are the same. – Kevin Fegan – 2013-12-25T15:56:37.033

2For this you may add cursor:default and cursor:text respectively : ) – T4NK3R – 2014-07-14T17:14:41.547

11Make 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 – 2011-07-07T22:39:56.223

11Be very wary about turning off browser UI expectations on ALL code except for one item. What about list items <li /> text, for example? – Jason T Featheringham – 2011-11-12T07:13:45.963

111

In the above solutions selection is stopped, but the user still thinks you can select text because the cursor still changes. To keep it static, you'll have to set your CSS cursor:

.noselect {
    cursor: default;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
<p>
  Selectable text.
</p>
<p class="noselect">
  Unselectable text.
</p>

This will make your text totally flat, like it would be in a desktop application.

ZECTBynmo

Posted 2009-05-05T20:29:18.237

Reputation: 1 694

"Flat" as opposed to what? – kojow7 – 2018-02-09T20:55:53.963

@kojow7 As opposed to "layered". Instead of text floating on top of the other elements. It is similar to the difference between SVG and PNG images. – Yeti – 2018-09-19T09:35:59.937

101

You can do so in Firefox and Safari (Chrome also?)

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

seanmonstar

Posted 2009-05-05T20:29:18.237

Reputation: 9 642

1Doesn't work on PNG-images with transparent areas: The will always select in a light blue… Any workaround? – AvL – 2013-09-18T21:12:27.273

107I wouldn't recommend doing this, because it doesn't actually fix the issue; disabling text selection - it merely hides it. This can lead to bad usability, because if I drag my cursor around the page I could be selecting any arbitrary text without knowing it. This can cause all kinds of weird usability "bugs". – Keithamus – 2011-02-02T15:01:40.067

75

Workaround for WebKit:

/* Disable tap highlighting */
-webkit-tap-highlight-color: rgba(0,0,0,0);

I found it in a CardFlip example.

Alex

Posted 2009-05-05T20:29:18.237

Reputation: 769

1Using transparent in lieu of rgba also works in Chrome 42 on Android. – Clint Pachl – 2015-04-29T20:46:35.377

66

I like the hybrid CSS + jQuery solution.

To make all elements inside <div class="draggable"></div> unselectable, use this CSS:

.draggable {
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -o-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

.draggable input { 
    -webkit-user-select: text; 
    -khtml-user-select: text; 
    -moz-user-select: text; 
    -o-user-select: text; 
    user-select: text; 
 }

And then, if you're using jQuery, add this inside a $(document).ready() block:

if (($.browser.msie && $.browser.version < 10) || $.browser.opera) $('.draggable').find(':not(input)').attr('unselectable', 'on');

I figure you still want any input elements to be interactable, hence the :not() pseudo-selector. You could use '*' instead if you don't care.

Caveat: IE9 may not need this extra jQuery piece, so you may want to add a version check in there.

Tom Auger

Posted 2009-05-05T20:29:18.237

Reputation: 10 641

5Use -ms-user-select: none; (for IE10) and your jQuery "if" should be this: if (($.browser.msie && $.browser.version < 10) || $.browser.opera) – mhenry1384 – 2013-01-31T03:42:15.347

Be careful man !!! To make it selectable in firefox you must use -moz-user-select: Normal; – Nicolas Thery – 2013-03-10T16:53:37.747

@nicholasthery http://www.w3.org/TR/2000/WD-css3-userint-20000216#user-select

– Tom Auger – 2013-03-11T13:44:40.677

7

@mhenry1384 jQuery.browser has been deprecated as of version 1.3 and has been removed in version 1.9 - http://api.jquery.com/jQuery.browser

– WynandB – 2013-03-14T23:58:05.147

@Wynand Good point. But what sort of "feature detection" exists to determine which CSS property to use? – Tom Auger – 2013-03-15T13:28:36.733

@TomAuger You could use jQuery.support, it allows you to check for single features : Link

– Aequanox – 2013-03-28T10:10:17.880

Yeah, but what exactly are you going to query in terms of support? I wasn't aware that you could query support for a particular CSS property... – Tom Auger – 2013-03-28T13:59:45.867

63

.hidden:after {
    content: attr(data-txt);
}
<p class="hidden" data-txt="Some text you don't want to be selected"></p>

It's not the best way, though.

Ale

Posted 2009-05-05T20:29:18.237

Reputation: 1 581

1You could also use title as the attribute. – Toothbrush – 2014-05-07T16:50:34.180

5That is a very creative solution. Especially if it used the title attribute because that would probably be better for screen readers. – pseudosavant – 2014-09-16T21:49:55.613

4

I tried it (JSBin) and it doesn't work in IE. Unfortunately older IEs are the only ones that user-select doesn't work for.

– pseudosavant – 2014-09-16T21:58:23.067

1This is a great non-JS alternative that works in Chrome! Awesome! – saricden – 2018-11-06T15:05:40.843

59

You can use CSS or JavaScript for that, JavaScript way is supported in Older browsers like Old IEs as well, but if it's not your case, use the CSS way then:

HTML/JavaScript:

<html onselectstart='return false;'>
  <body>
    <h1>This is the Heading!</h1>
    <p>And I'm the text, I won't be selected if you select me.</p>
  </body>
</html>

HTML/CSS:

.not-selectable {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
<body class="not-selectable">
  <h1>This is the Heading!</h1>
  <p>And I'm the text, I won't be selected if you select me.</p>
</body>

Alireza

Posted 2009-05-05T20:29:18.237

Reputation: 43 514

57

For Internet Explorer in addition, you need to add pseudo class focus (.ClassName:focus) and outline-style:none.

.ClassName,
.ClassName:focus {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    outline-style:none;/*IE*/
}

Elad Shechter

Posted 2009-05-05T20:29:18.237

Reputation: 2 316

3

This does work in IE so long as the selection starts on an element with the className class. See this JSBin.

– pseudosavant – 2014-09-16T22:01:32.727

47

Working

CSS:

 -khtml-user-select: none;
 -moz-user-select: none;
 -ms-user-select: none;
  user-select: none;
 -webkit-touch-callout: none;
 -webkit-user-select: none;

This should be working, but it won't work for the old browsers. There is a browser compatibility issue.

suraj rawat

Posted 2009-05-05T20:29:18.237

Reputation: 2 628

The unprefixed CSS property must be strictly at the end of list of prefixed versions of the property. It is good right practice, other is bad practice making an "new IE" from Chrome/Webkit and leading to so much UGLY THINGS as introducing -webkit prefix support in not webkit browsers. Look, this was already in 2012: https://dev.opera.com/articles/opera-mobile-emulator-webkit-prefix-support/

– FlameStorm – 2017-03-21T22:52:27.400

And I quote: This is because through our site compatibility work, we have experienced that many authors of (especially mobile) sites only use -webkit- prefixed CSS, thereby ignoring other vendor prefixes and not even including an unprefixed equivalent. This leads to a reduced user experience on Opera and Firefox, which don’t receive the same shiny effects such as transitions, gradients and the like, even if the browser supported those effects. – FlameStorm – 2017-03-21T22:52:47.690

46

-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-o-user-select: none;
user-select: none;

*.unselectable {
   -moz-user-select: -moz-none;
   -khtml-user-select: none;
   -webkit-user-select: none;
   user-select: none;
}
<div id="foo" unselectable="on" class="unselectable">...</div>
function makeUnselectable(node) {
    if (node.nodeType == 1) {
        node.unselectable = true;
    }
    var child = node.firstChild;
    while (child) {
        makeUnselectable(child);
        child = child.nextSibling;
    }
}

makeUnselectable(document.getElementById("foo"));
-webkit-user-select:none;
-moz-user-select:none;
onselectstart="return false;"
::selection { background: transparent; }
::-moz-selection { background: transparent; }

* {
-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;
}
<div class="draggable"></div>
.draggable {
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -o-user-select: none;
    user-select: none;
}

.draggable input { 
    -webkit-user-select: text; 
    -khtml-user-select: text; 
    -moz-user-select: text; 
    -o-user-select: text; 
    user-select: text; 
 }
if ($.browser.msie) $('.draggable').find(':not(input)').attr('unselectable', 'on');

Gaurang

Posted 2009-05-05T20:29:18.237

Reputation: 1 678

46

For those who have trouble achieving the same in the Android browser with the touch event, use:

html,body{
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -webkit-tap-highlight-color: rgba(0,0,0,0);
    -webkit-tap-highlight-color: transparent;
}

Beep.exe

Posted 2009-05-05T20:29:18.237

Reputation: 1 150

@Volker E. well, he DOES say that it's for the android browser only, you could just add that to the other answers instead of being sarcastic. – dudewad – 2016-01-07T21:33:05.853

44

If you are using Less and Bootstrap you could write:

.user-select(none);

Codler

Posted 2009-05-05T20:29:18.237

Reputation: 7 260

33

Aside from the Mozilla-only property, no, there is no way to disable text selection with just standard CSS (as of now).

If you notice, Stack Overflow doesn't disable text selection for their navigation buttons, and I would recommend against doing so in most cases, since it modifies normal selection behavior and makes it conflict with a user's expectations.

hbw

Posted 2009-05-05T20:29:18.237

Reputation: 13 525

5If you're selecting a set of comments from a chat thread and each comment has an upvote/downvote button next to it, then it would be nice to select the text without the other stuff. That's what the user expects or wants. He doesn't want to copy/paste the button labels with every comment. – Mnebuerquo – 2013-08-03T16:52:21.457

2And what if you for example double click a button which instead of redirecting you to another page opens a div? then the text for the button will be selected due to the double-click! – Gigala – 2014-07-25T11:32:26.003

Make the things you want selectable - selectable... and nothing else. – sheriffderek – 2016-03-26T01:28:06.400

While I agree that it changes behaviour the user expects, it would make sense for things like the "Add Comment" button that is sitting next to this form field ... – X-Istence – 2009-05-05T20:40:33.793

But doesn't that expose needless implementation details? An input or button's text can't be selected. – None – 2009-05-05T20:40:46.197

@anon: Most users will probably not try to select the text of your button, so in practice, it shouldn't really matter much. Besides, in order to do so, they will have to start selecting outside of the button—if they click inside the button itself, the onclick handler will activate instead. Plus, certain browsers (e.g. Safari) actually let you select the text of normal buttons… – hbw – 2009-05-05T20:49:07.767

Selecting records in a table is another exception. If you want to enable holding shift/control to select and highlight multiple records, then you have to disable text-selection. – bvdb – 2017-08-28T08:12:48.850

32

This works in some browsers:

::selection{ background-color: transparent;}
::moz-selection{ background-color: transparent;}
::webkit-selection{ background-color: transparent;}

Simply add your desired elements/ids in front of the selectors separated by commas without spaces, like so:

h1::selection,h2::selection,h3::selection,p::selection{ background-color: transparent;}
h1::moz-selection,h2::moz-selection,h3::moz-selection,p::moz-selection{ background-color: transparent;}
h1::webkit-selection,h2::webkit-selection,h3::webkit-selection,p::webkit-selection{ background-color: transparent;}

The other answers are better; this should probably be seen as a last resort/catchall.

r3wt

Posted 2009-05-05T20:29:18.237

Reputation: 2 928

2There are few things that can be known for sure, but this solution definitely doesn't work in all browsers. – Volker E. – 2014-09-30T09:27:40.353

1they why you say all browsers.. clearly you can edit better your answer – scx – 2014-11-13T14:03:21.300

@scx the goal of the answer was to provide a starting point. as you can see, there are much better answers than mine anyway. if i have time to take another crack at it in the future, i'll experiment and see what i can come up with. – r3wt – 2014-11-14T11:13:01.417

31

Suppose there are two div like this

.second {
  cursor: default;
  user-select: none;
  -webkit-user-select: none;
  /* Chrome/Safari/Opera */
  -moz-user-select: none;
  /* Firefox */
  -ms-user-select: none;
  /* IE/Edge */
  -webkit-touch-callout: none;
  /* iOS Safari */
}
<div class="first">
  This is my first div
</div>

<div class="second">
  This is my second div
</div>

Set cursor to default so that it will give a unselectable feel to user/

Prefix need to be use to support it in all browsers without prefix this may not work in all the answers.

Gaurav Aggarwal

Posted 2009-05-05T20:29:18.237

Reputation: 7 213

28

NOTE:

The correct answer is correct in that it prevents you from being able to select the text. However, it does not prevent you from being able to copy the text, as I'll show with the next couple of screenshots (as of 7th Nov 2014).

Before we have selected anything

After we have selected

The numbers have been copied

As you can see, we were unable to select the numbers, but we were able to copy them.

Tested on: Ubuntu, Google Chrome 38.0.2125.111.

Luke Madhanga

Posted 2009-05-05T20:29:18.237

Reputation: 2 579

1I've had the same problem. On Mac Chrome 48.0.2564.116 and on Mac Safari 9.0.3. Notably, Mac Firefox 43.0 doesn't copy the character, but sticks extra endlines between them.

What should be done about this? – NHDaly – 2016-03-05T01:34:58.107

27

Add this to the first div in which you want to disable the selection for text:

onmousedown='return false;' 
onselectstart='return false;'

Chase1986

Posted 2009-05-05T20:29:18.237

Reputation: 578

27

This will be useful if color selection is also not needed:

::-moz-selection { background:none; color:none; }
::selection { background:none; color:none; }

...all other browser fixes. It will work in Internet Explorer 9 or later.

karthipan raj

Posted 2009-05-05T20:29:18.237

Reputation: 620

1Make that color: inherit; maybe. – Yaakov Ainspan – 2016-07-28T01:25:09.913

yeah I love it. It's css selector level 3 according to Mozilla docs

– Bariq Dharmawan – 2018-01-28T10:37:47.320

23

To get the result I needed I found I had to use both ::selection and user-select

input.no-select:focus { 
    -webkit-touch-callout: none; 
    -webkit-user-select: none; 
    -khtml-user-select: none; 
    -moz-user-select: none; 
    -ms-user-select: none; 
    user-select: none; 
}

input.no-select::selection { 
    background: transparent; 
}

input.no-select::-moz-selection { 
    background: transparent; 
}

SemanticZen

Posted 2009-05-05T20:29:18.237

Reputation: 756

21

This is not CSS, but it is worth a mention:

jQuery UI Disable Selection:

$("your.selector").disableSelection();

Automatico

Posted 2009-05-05T20:29:18.237

Reputation: 6 540

22Deprecated as of version 1.9... – adamb – 2013-06-18T21:18:15.553

20

Check my solution without JavaScript:

jsFiddle

li:hover {
    background-color: silver;
}
#id1:before {
    content: "File";
}
#id2:before {
    content: "Edit";
}
#id3:before {
    content: "View";
}
<ul>
    <li><a id="id1" href="www.w1.com"></a>
    <li><a id="id2" href="www.w2.com"></a>
    <li><a id="id3" href="www.w3.com"></a>
</ul>

Popup menu with my technique applied: http://jsfiddle.net/y4Lac/2/

zgnilec

Posted 2009-05-05T20:29:18.237

Reputation: 1 876

20

Though this pseudo-element was in drafts of CSS Selectors Level 3, it was removed during the Candidate Recommendation phase, as it appeared that its behavior was under-specified, especially with nested elements, and interoperability wasn't achieved.

It's being discussed in How ::selection works on nested elements.

Despite it is being implemented in browser, you can make an illusion of text not being selected by using the same color and background color on selection as of the tab design (in your case).

Normal CSS Design

p { color: white;  background: black; }

On selection

p::-moz-selection { color: white;  background: black; }
p::selection      { color: white;  background: black; }

Disallowing users to select the text will raise usability issues.

Suraj Naik

Posted 2009-05-05T20:29:18.237

Reputation: 443

This must be why Netbeans auto-completion has no idea what I am talking about! – halfer – 2014-04-26T20:16:19.213

15

I have learned from CSS-Tricks website.

user-select: none;

And this also:

::selection{ background-color: transparent;}
::moz-selection{ background-color: transparent;}
::webkit-selection{ background-color: transparent;}

Mohammed Javed

Posted 2009-05-05T20:29:18.237

Reputation: 599

13

Quick hack update: March 2017 -from CSS-Tricks

If you put the value 'none' for all the CSS user select attributes as showed in below, there is a problem which can be still occurred by this.

.div{
  -webkit-user-select: none; /* Chrome all / Safari all */
  -moz-user-select: none;   /* Firefox all */
  -ms-user-select: none;  /* IE 10+ */
   user-select: none;  /* Likely future */ 
}

As CSS-Trick says the problems is

  • WebKit still allows the text to be copied if you select elements around it.

So you can also use the below one instead to enforce that an entire element getting selected which is the solution for the problem. All you have to do is changing the value 'none' to 'all' which would look like this

.force-select {  
  -webkit-user-select: all;  /* Chrome 49+ */
  -moz-user-select: all;     /* Firefox 43+ */
  -ms-user-select: all;      /* No support yet */
  user-select: all;          /* Likely future */   
}

Kaz

Posted 2009-05-05T20:29:18.237

Reputation: 175

10

Try to use this one:

::selection {
    background: transparent;
}

And if you wish to specify not select inside a specific element, just put the element class or id before the selection rule, such as:

.ClassNAME::selection {
    background: transparent;
}
#IdNAME::selection {
    background: transparent;
}

mustafa-elhelbawy

Posted 2009-05-05T20:29:18.237

Reputation: 454

10

 -webkit-user-select: none;  
  -moz-user-select: none;    
  -ms-user-select: none;      
  user-select: none;

Hetal Rupareliya

Posted 2009-05-05T20:29:18.237

Reputation: 337

10

This highlighting effect is due to the action called hover(onMouseHover). When you will hover on any tab it's color will be changed. Just say for example.

<div class="menu">
 <ul class="effect">
   <li>Questions </li>
   <li>JOBS </li>
   <li>Users</li>
 </ul>
</div>

<!-- CSS CODE -->

.effect:hover{
   color: none;
}

You can give any color if you wanted to get it highlighted, else yo u can give none.

Pushp Singh

Posted 2009-05-05T20:29:18.237

Reputation: 413

9

You can use User-select property as below for that..

p {  
     -webkit-user-select: none;  /* Chrome all / Safari all */
     -moz-user-select: none;     /* Firefox all */
     -ms-user-select: none;      /* IE 10+ */
      user-select: none;          /* Likely future */             
   }

Link for the Detailed Description

Chirag Dave

Posted 2009-05-05T20:29:18.237

Reputation: 129

8

If you want to disable selection and highlighting for the whole page you can easily do this with css

* {
    -webkit-touch-callout: none; /* iOS Safari */
      -webkit-user-select: none; /* Safari */
       -khtml-user-select: none; /* Konqueror HTML */
         -moz-user-select: none; /* Firefox */
          -ms-user-select: none; /* Internet Explorer/Edge */
              user-select: none; /* Non-prefixed version, currently
                                    supported by Chrome and Opera */
  }

jasonleonhard

Posted 2009-05-05T20:29:18.237

Reputation: 1 658

7

With CSS-

div {
  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
  user-select: none;
  -o-user-select: none;

  "unselectable='on' onselectstart="return false;"
  onmousedown="return false;
}
<div>
  Blabla
  <br/> More Blabla
  <br/> More Blabla...
</div>

Abrar Jahin

Posted 2009-05-05T20:29:18.237

Reputation: 6 093

6

Try insert this rows to CSS and call the "disHighlight" at class property:

.disHighlight{
    user-select: none;
    -webkit-user-select: none;
    -ms-user-select: none;
    -webkit-touch-callout: none;
    -o-user-select: none;
    -moz-user-select: none;
}

user1012506

Posted 2009-05-05T20:29:18.237

Reputation: 928

6

Easily done with:

-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;

alternatively:

Let's say you have a <h1 id="example">Hello, World!</h1>, What you will have to do is remove the innerHTML of that h1: in this case Hello, World. Then you will have to go to css and do this:

#example::before //You can ofc use **::after** as well.
{
  content: 'Hello, World!'; //Both single-quotes and double-quotes can be used here.

  display: block; //To make sure it works fine in every browser.
}

Now it simply thinks it is a block-element, and not a text.

codeWithMe

Posted 2009-05-05T20:29:18.237

Reputation: 182

4

Even better, you can disable text selection.

if you like SASS (SCSS), and you don't want to use compass you can do this

styles.scss

@mixin user-select($select) {
  -webkit-touch-callout:#{$select};
  @each $pre in -webkit-, -moz-, -ms-, -o-, -khtml- {
  #{$pre + user-select}: #{$select};
  } 
  #{user-select}: #{$select};
}

.no-select {
  @include user-select(none);
}

Yevgeniy Afanasyev

Posted 2009-05-05T20:29:18.237

Reputation: 7 563

4

I combined the various browser css with the unselectable tag required for IE < 9.

<style>
[unselectable="on"] {
    -webkit-user-select: none; /* Safari */
    -moz-user-select: none; /* Firefox */
    -ms-user-select: none; /* IE10+/Edge */
    user-select: none; /* Standard */
}
</style>
<div unselectable="on">Unselectable Text</div>

oMiKeY

Posted 2009-05-05T20:29:18.237

Reputation: 2 943

1

Maybe you can use this solution throught :before

nav li {
 display: inline-block;
 position: relative;
}

nav li a {
 display: inline-block;
 padding: 10px 20px;
}

nav li a:hover {
 color: red;
}

nav li.disabled:before {
 content: '';
 position: absolute;
 top: 0;
 left: 0;
 bottom: 0;
 right: 0;
}
<nav>
 <ul>
 <li><a href="#">Link</a></li>
 <li class="disabled"><a href="#">Link</a></li>
 <li><a href="#">Link</a></li>
 </ul>
</nav>

JsFiddle - https://jsfiddle.net/grinmax_/9L1cckxu/

grinmax

Posted 2009-05-05T20:29:18.237

Reputation: 1 387

1

::selection {background: transparent; color: transparent;}

::-moz-selection {background: transparent; color: transparent;}

Navneet Kumar

Posted 2009-05-05T20:29:18.237

Reputation: 59