165

Here is an interesting CSS questions for you!

I have a textarea with a transparent background overlaying some TEXT that I'd like to use as a sort of watermark. The text is large and takes up a majority of the textarea. It looks nice, the problem is when the user clicks in the textarea it sometimes selects the watermark text instead. I want the watermark text to never be selectable. I was expecting if something was lower in the z-index it would not be selectable but browsers don't seem to care about z-index layers when selecting items. Is there a trick or way to make it so this DIV is never selectable?

Whozumommy
  • 3,203
  • 7
  • 29
  • 22

12 Answers12

242

I wrote a simple jQuery extension to disable selection some time back: Disabling Selection in jQuery. You can invoke it through $('.button').disableSelection();

Alternately, using CSS (cross-browser):

.button {
        user-select: none;
        -moz-user-select: none;
        -khtml-user-select: none;
        -webkit-user-select: none;
        -o-user-select: none;
} 
aleemb
  • 31,265
  • 19
  • 98
  • 114
  • @kasperTaeymans But it is in a [W3C working draft](http://www.w3.org/TR/2000/WD-css3-userint-20000216#user-select)... I'd include it just in case. – Camilo Martin Sep 01 '12 at 01:20
  • 2
    Not to take anything away from the original answer, which I upvoted, but it is 3+ years old. So I added an answer below (http://stackoverflow.com/questions/924916/is-there-a-way-to-make-a-div-unselectable/24831222#24831222) with an added setting for touch interface. – Anne Gunn Jul 18 '14 at 18:07
  • That's what I wanted for movable bootstrap modal header! Thanks! – NoWar Sep 19 '18 at 03:24
70

The following CSS code works almost modern browser:

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

For IE, you must use JS or insert attribute in html tag.

<div id="foo" unselectable="on" class="unselectable">...</div>
KimKha
  • 4,370
  • 1
  • 37
  • 45
51

Just updating aleemb's original, much-upvoted answer with a couple of additions to the css.

We've been using the following combo:

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

We got the suggestion for adding the webkit-touch entry from:
http://phonegap-tips.com/articles/essential-phonegap-css-webkit-touch-callout.html

2015 Apr: Just updating my own answer with a variation that may come in handy. If you need to make the DIV selectable/unselectable on the fly and are willing to use Modernizr, the following works neatly in javascript:

    var userSelectProp = Modernizr.prefixed('userSelect');
    var specialDiv = document.querySelector('#specialDiv');
    specialDiv.style[userSelectProp] = 'none';
Anne Gunn
  • 2,347
  • 1
  • 28
  • 42
  • applying `user-select: none` to a `div` has no effect whatsoever. i'm pretty sure `user-select` is for text only. are there any other ways to make a `div` unselectable? – oldboy May 18 '17 at 06:04
25

You can use pointer-events: none; in your CSS

div {
  pointer-events: none;
}
Linh Dam
  • 2,033
  • 1
  • 19
  • 18
  • 1
    This is exactly what I needed to avoid my
    grabbing the selection from a hidden div. Thanks!
    – Jason Oct 30 '20 at 21:30
22

As Johannes has already suggested, a background-image is probally the best way to achieve this in CSS alone.

A JavaScript solution would also have to affect "dragstart" to be effective across all popular browsers.

JavaScript:

<div onselectstart="return false;" ondragstart="return false;">your text</div>

jQuery:

var _preventDefault = function(evt) { evt.preventDefault(); };
$("div").bind("dragstart", _preventDefault).bind("selectstart", _preventDefault);

Rich

kim3er
  • 6,306
  • 4
  • 41
  • 69
6

Wouldn't a simple background image for the textarea suffice?

Joey
  • 344,408
  • 85
  • 689
  • 683
5

you can try this:

<div onselectstart="return false">your text</div>
Fortega
  • 19,463
  • 14
  • 75
  • 113
4

WebKit browsers (ie Google Chrome and Safari) have a CSS solution similar to Mozilla's -moz-user-select:none

.no-select{    
    -webkit-user-select: none;
    cursor:not-allowed; /*makes it even more obvious*/
}
James
  • 4,117
  • 2
  • 18
  • 13
2

Also in IOS if you want to get rid of gray semi-transparent overlays appearing ontouch, add css:

-webkit-tap-highlight-color: rgba(0,0,0,0);
-webkit-touch-callout: none;
Artjom Kurapov
  • 6,115
  • 4
  • 32
  • 42
0

Yes, there are multiple ways.

  1. You could simply add the user-select CSS declaration and set it to none, like this

    div {
        user-select: none;
    }
    
  2. Also you could accomplish this with the CSS ::selection selector and set the selection background color to match your own. This could get tricky.:

    p::selection {
        background: rgba(0, 0, 0, 0)
    }
    

Option 1 being the best option in most cases for obvious reasons!

-1

Use

onselectstart="return false"

it prevents copying your content.

Anuraj
  • 2,551
  • 21
  • 26
-1

Make sure that you set position explicitly as absolute or relative for z-index to work for selection. I had a similar issue and this solved it for me.

Eric Grotke
  • 4,651
  • 3
  • 21
  • 19