Is there a way to make text unselectable on an HTML page?

117,095

Solution 1

In most browsers, this can be achieved using CSS:

*.unselectable {
   -moz-user-select: -moz-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, 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"));

Solution 2

<script type="text/javascript">

/***********************************************
* Disable Text Selection script- © Dynamic Drive DHTML code library (www.dynamicdrive.com)
* This notice MUST stay intact for legal use
* Visit Dynamic Drive at http://www.dynamicdrive.com/ for full source code

***********************************************/


function disableSelection(target){

    if (typeof target.onselectstart!="undefined") //IE route
        target.onselectstart=function(){return false}

    else if (typeof target.style.MozUserSelect!="undefined") //Firefox route
        target.style.MozUserSelect="none"

    else //All other route (ie: Opera)
        target.onmousedown=function(){return false}

    target.style.cursor = "default"
}



//Sample usages
//disableSelection(document.body) //Disable text selection on entire body
//disableSelection(document.getElementById("mydiv")) //Disable text selection on element with id="mydiv"


</script>

EDIT

Code apparently comes from http://www.dynamicdrive.com

Solution 3

All of the correct CSS variations are:

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

Solution 4

Try this:

<div onselectstart="return false">some stuff</div>

Simple, but effective... works in current versions of all major browsers.

Solution 5

For Firefox you can apply the CSS declaration "-moz-user-select" to "none". Check out their documentation, user-select.

It's a "preview" of the future "user-select" as they say, so maybe Opera or WebKit-based browsers will support that. I also recall finding something for Internet Explorer, but I don't remember what :).

Anyway, unless it's a specific situation where text-selecting makes some dynamic functionality fail, you shouldn't really override what users are expecting from a webpage, and that is being able to select any text they want.

Share:
117,095
Tyler
Author by

Tyler

     I run an iPhone app consultancy called Bynomial. Please let me know if you're interested in app development! I'm always looking for good coders and good clients.      My background: I love math -- I got a PhD in it from the Courant Institute at NYU in 2006. After that I was a coder at Google for a few years, and in 2009 started Bynomial.

Updated on April 17, 2020

Comments

  • Tyler
    Tyler about 4 years

    I'm building an HTML UI with some text elements, such as tab names, which look bad when selected. Unfortunately, it's very easy for a user to double-click a tab name, which selects it by default in many browsers.

    I might be able to solve this with a JavaScript trick (I'd like to see those answers, too) -- but I'm really hoping there's something in CSS/HTML directly that works across all browsers.

  • Brandon DuRette
    Brandon DuRette over 15 years
    Likewise in Safari/Chrome/etc. -khtml-user-select:none;
  • Andrew Harry
    Andrew Harry over 15 years
    This is what flickr does
  • Andrew Harry
    Andrew Harry over 15 years
    Is this likely to appear in the CSS standards though?
  • Tyler
    Tyler almost 15 years
    This doesn't work for me in firefox.
  • vsync
    vsync over 14 years
    This is IE only attribute. which makes it redundant.
  • jayarjo
    jayarjo about 14 years
    Is there any update for the Opera or making elements unselectable still not supported?
  • HRJ
    HRJ almost 14 years
    Why are you changing the cusor style to 'default' in the last case? Otherwise +1
  • HRJ
    HRJ almost 14 years
    Infact, you are changing it in all cases (indent is misleading)
  • Doug
    Doug almost 14 years
    This kind of hack is terrible. I'd avoid it personally.
  • Lee
    Lee over 13 years
    Worked perfectly for our app (we only target IE users).
  • Hubro
    Hubro over 13 years
    I guess body might not be accessible in DOM before it has content, thus you can't set it's style before you write something in the document.
  • venimus
    venimus about 13 years
    you can use this selector [unselectable=on]{...} then you avoid putting extra class
  • EricP
    EricP over 12 years
    According to dev.l-c-n.com/CSS3-selectors/browser-support.php , this selector should be supported in IE8 and above, and possibly IE7.
  • Tim Down
    Tim Down over 12 years
    @JoeCoder: Yes, I believe attribute selectors do work in IE 7, although not IE 6.
  • undefined
    undefined over 11 years
    Just curious, is there an advantage to using *.unselectable over .unselectable in the stylesheet?
  • Tim Down
    Tim Down over 11 years
    @BrianMortenson: None at all: they are equivalent. I have a very old habit of including the * in that kind of selector to remind myself explicitly that I'm matching all tag names. However, I no longer find it helpful and it's now just pure habit, so I've pretty much stopped doing it now.
  • ericsoco
    ericsoco almost 11 years
    funny that @TimDown harvested another 113 rep by copying his answer from this question's duplicate. oh wait! <click> 114 ;)
  • Tim Down
    Tim Down almost 11 years
    @ericsoco: Yeah. It's an interesting issue: if others have posted answers that people are upvoting and I think I have a better answer, should I post it? The system still allows people to find, view and vote on answers to closed questions, after all. I can't deny that desire for rep has occasionally motivated me to add an answer to a duplicate question on a pet subject rather than vote to close it.
  • ericsoco
    ericsoco almost 11 years
    of course you should and of course you should post your answers everywhere they can be found. the point of answering, ultimately, is not about rep -- it's about providing answers in places they can be found. i'm all for it. </OT>
  • Erik  Reppen
    Erik Reppen over 10 years
    @venimus I would favor classes over xpath selectors like [unselectable=on] in CSS. In jquery they're good if you narrow down to an immediate container first but in CSS, selectors are parsed right to left so it's still a blanket check of every element and every element's unselectable attribute using the performance-meh xpath engine. Likewise, I believe, with the querySelector API which I'm guessing typically hooks into the CSS/xpath selector engines directly. This may change over time as browsers find perf tweaks but I would definitely keep this in mind when supporting IE<=8, maybe <=9.
  • venimus
    venimus over 10 years
    Probably you are right, but I think early optimizations are evil. Also you won't need the JS if you use [unselectable=on] * {...}
  • Tim Down
    Tim Down over 10 years
    @venimus: You can't avoid the JS if you want IE <= 9 support and don't want to put unselectable="on" on every element. All you can avoid with your selector is adding class="unselectable".
  • Basil Bourque
    Basil Bourque over 9 years
    According to this Answer, the order of those two webkit settings may be critical, where the -webkit-user-select: should come before the -webkit-touch-callout:. I have not verified this.
  • Alexis Wilke
    Alexis Wilke over 8 years
    The tiny little problem with this method are the links, as you mentioned, and any other interactions you'd want to have with the main window...
  • Mark Hughes
    Mark Hughes over 7 years
    This was the only way I could get the effect needed for text selection happening in IE11 when doing a shift-click select in an ag-Grid.