251

I would like to add text to my webpage as a label and make it unselectable.

In other words, When the mouse cursor is over the text I would like it to not turn into a text selecting cursor at all.

A good example of what I'm trying to achieve is the buttons on this website (Questions,Tags,Users,...)

0

4 Answers 4

389

You can't do this with plain vanilla HTML, so JSF can't do much for you here as well.

If you're targeting decent browsers only, then just make use of CSS3:

.unselectable { -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } 
<label class="unselectable">Unselectable label</label> 

If you'd like to cover older browsers as well, then consider this JavaScript fallback:

<!doctype html> <html lang="en"> <head> <title>SO question 2310734</title> <script> window.onload = function() { var labels = document.getElementsByTagName('label'); for (var i = 0; i < labels.length; i++) { disableSelection(labels[i]); } }; function disableSelection(element) { if (typeof element.onselectstart != 'undefined') { element.onselectstart = function() { return false; }; } else if (typeof element.style.MozUserSelect != 'undefined') { element.style.MozUserSelect = 'none'; } else { element.onmousedown = function() { return false; }; } } </script> </head> <body> <label>Try to select this</label> </body> </html> 

If you're already using jQuery, then here's another example which adds a new function disableSelection() to jQuery so that you can use it anywhere in your jQuery code:

<!doctype html> <html lang="en"> <head> <title>SO question 2310734 with jQuery</title> <script src="http://code.jquery.com/jquery-latest.min.js"></script> <script> $.fn.extend({ disableSelection: function() { this.each(function() { if (typeof this.onselectstart != 'undefined') { this.onselectstart = function() { return false; }; } else if (typeof this.style.MozUserSelect != 'undefined') { this.style.MozUserSelect = 'none'; } else { this.onmousedown = function() { return false; }; } }); } }); $(document).ready(function() { $('label').disableSelection(); }); </script> </head> <body> <label>Try to select this</label> </body> </html> 
Sign up to request clarification or add additional context in comments.

9 Comments

This answer has a problem, and it does not work in all cases any more. Other browsers use their own vendor prefixes, and you are using MozUserSelect only. New browsers will use no prefix. Look at the list of all possible javascript prefixes: ['Moz', 'Webkit', 'ms', 'O', 'Khtml', ''] /*with empty string for no prefix*/. You should correctly deal with camelCase. And it's a serious bug that you are overwriting onselectstart and onmousedown event handlers with your function, so previously attached handlers do not work any more. I can Update your code if you like
@BalusC as far as I see here developer.mozilla.org/en-US/docs/Web/CSS/user-select, you still can't do this cross browser with CSS only (old IE, Opera and Firefox). So a good hybrid solution is needed
And @Blowsie has reported problems in comments.
If you do end up adding the disableSelection to jQuery - I did, and it works great, but give it another name. In case you end up using jQuery UI there's a name conflict when using plugins like resizable. Just a heads up.
|
188

No one here posted an answer with all of the correct CSS variations, so here it is:

.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; }
<p class="not-selectable">Not-selectable text</p>

8 Comments

These do work well in modern browsers, but be aware that older ones like IE7 will not support this.
In Chrome 18, this is only a visual effect, the text is still selectable.
Can still select text in Opera 11
Can still select text in Opera.
@RonRoyston the questions is about selecting not copying. But maybe u want this.
|
63

The full modern solution to your problem is purely CSS-based, but note that older browsers won't support it, in which cases you'd need to fallback to solutions such as the others have provided.

So in pure CSS:

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

However the mouse cursor will still change to a caret when over the element's text, so you add to that:

cursor: default; 

Modern CSS is pretty elegant.

5 Comments

you call that modern? having to specify the same thing 6 times?
yeah I hate the browser prefixes too but oh well they have a history of not agreeing so we got used to having these around.
@FlavorScape I use less, so I only have to write this snippet once! :)
You can also use SASS and specify a mixin for that.
Specifying the cursor seems to be no longer needed. It will change to default automatically with the correct variation of user-select: none. Tested in Firefox 61.0.1 and Vivaldi 1.15.1147.47.
12

I altered the jQuery plugin posted above so it would work on live elements.

(function ($) { $.fn.disableSelection = function () { return this.each(function () { if (typeof this.onselectstart != 'undefined') { this.onselectstart = function() { return false; }; } else if (typeof this.style.MozUserSelect != 'undefined') { this.style.MozUserSelect = 'none'; } else { this.onmousedown = function() { return false; }; } }); }; })(jQuery); 

Then you could so something like:

$(document).ready(function() { $('label').disableSelection(); // Or to make everything unselectable $('*').disableSelection(); }); 

1 Comment

This was a great answer, but unfortunately it got outdated. See my comment to @BalusC answer

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.