How to make HTML Text unselectable

280,123

Solution 1

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>

Solution 2

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>

Solution 3

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.

Solution 4

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();
});
Share:
280,123

Related videos on Youtube

Ben
Author by

Ben

Updated on April 11, 2020

Comments

  • Ben
    Ben about 4 years

    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,...)

  • Jarrod Nettles
    Jarrod Nettles almost 13 years
    These do work well in modern browsers, but be aware that older ones like IE7 will not support this.
  • j08691
    j08691 about 12 years
    In Chrome 18, this is only a visual effect, the text is still selectable.
  • Almo
    Almo about 12 years
    Can still select text in Opera 11
  • FlavorScape
    FlavorScape almost 12 years
    you call that modern? having to specify the same thing 6 times?
  • Vic Goldfeld
    Vic Goldfeld almost 12 years
    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.
  • Camilo Martin
    Camilo Martin almost 12 years
    @FlavorScape I use less, so I only have to write this snippet once! :)
  • Dan
    Dan almost 11 years
    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
  • Dan
    Dan almost 11 years
    This was a great answer, but unfortunately it got outdated. See my comment to @BalusC answer
  • Dan
    Dan almost 11 years
    @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
  • Dan
    Dan almost 11 years
    And @Blowsie has reported problems in comments.
  • Dan
    Dan almost 11 years
  • john-jones
    john-jones over 10 years
    Can still select text in Opera.
  • Raja
    Raja over 10 years
    For Opera, does the '-o-' prefix work?
  • Matt
    Matt almost 10 years
    @joeytwiddle Might be worth sticking it in just in case.
  • Bruno Finger
    Bruno Finger almost 10 years
    You can also use SASS and specify a mixin for that.
  • webdreamer
    webdreamer over 9 years
    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.
  • Ronnie Royston
    Ronnie Royston over 7 years
    CSS does not work in Chrome Version 56.0.2924.87 (64-bit). Still copies to clipboard...
  • Rohit Suthar
    Rohit Suthar over 7 years
    try like this - *.unselectable { ... }
  • Huelfe
    Huelfe about 7 years
    @RonRoyston the questions is about selecting not copying. But maybe u want this.
  • Sinthorion
    Sinthorion almost 6 years
    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.
  • CularBytes
    CularBytes almost 4 years
    That's why I love being a developer, now I found how to copy some piece of text they don't want me to copy. Just search for the problem they probably had :).
  • Jevon
    Jevon over 2 years
    I want to know how one would undo the jquery function. Like $(".element").mousedown(function() { $('body').disableSelection(); )}; $(window).mouseup(function() { $('body').undoThedisableSelectionFunction(); });
  • Jevon
    Jevon over 2 years
    You or someone here might do an easy job of answering this question stackoverflow.com/questions/70930570/…