anon
anon

Reputation:

How to disable text selection highlighting

For anchors that act like buttons (for example, the buttons on the sidebar of this Stack Overflow page titled Questions, Tags, and Users) or tabs, is there a CSS standard way to disable the highlighting effect if the user accidentally selects the text?

I realize that 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?

Upvotes: 6144

Views: 2780356

Answers (30)

Blowsie
Blowsie

Reputation: 40555

UPDATE January, 2017:

According to Can I use, the user-select + -webkit-user-select for Safari is enough to achieve desired behavior in all major browsers.


These are all of the available correct CSS variations:

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


Note that user-select is in standardization process (currently in a W3C working draft). It is not guaranteed to work everywhere and there might be differences in implementation among browsers. Also, browsers can drop support for it in the future.


More information can be found in Mozilla Developer Network documentation.

The values of this attribute are none, text, toggle, element, elements, all and inherit.

Upvotes: 8617

Rajilesh Panoli
Rajilesh Panoli

Reputation: 790

Have you tried this?

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

    pointer-events:none;
}

Upvotes: 15

Alessandro_Russo
Alessandro_Russo

Reputation: 2231

With SASS (SCSS syntax)

You can do this with a mixin:

// Disable selection
@mixin disable-selection {
    -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 */
}

// No selectable element
.no-selectable {
    @include disable-selection;
}

In an HTML tag:

<div class="no-selectable">TRY TO HIGHLIGHT. YOU CANNOT!</div>

Try it in this CodePen.

If you are using an autoprefixer you can remove other prefixes.

Browser compatibility here.

Upvotes: 58

jasonleonhard
jasonleonhard

Reputation: 13907

If you want to disable selection and highlighting for the whole page with CSS, you can easily apply it to all elements:

* {
    -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 */
}

Upvotes: 19

RixTheTyrunt
RixTheTyrunt

Reputation: 405

FIRST METHOD: ( TOTALLY NONSENSE ):

.no-select::selection, .no-select *::selection {
  background-color: Transparent;
}

.no-select { /* Sometimes I add this too. */
  cursor: default;
}
<span>RixTheTyrunt is da best!</span>
<br>
<span class="no-select">RixTheTyrunt is da best!</span>

Snippet:

.no-select::selection, .no-select *::selection {
  background-color: Transparent;
}

.no-select {
  /* Sometimes I add this too. */
  cursor: default;
}
<span>RixTheTyrunt is da best!</span>
<br>
<span class="no-select">RixTheTyrunt is da best!</span>

SECOND METHOD ( NO NONSENSE INCLUDED )

.no-select {
  user-select: none;
  -moz-user-select: none;
  -webkit-user-select: none;
}

Snippet:

.no-select {
  user-select: none;
  -moz-user-select: none;
  -webkit-user-select: none;
}
<span>RixTheTyrunt is da best!</span>
<br>
<span class="no-select">RixTheTyrunt is da best!</span>

First, solve the problem. Then, write the code.

John Johnson

Upvotes: 22

Shubham Garg
Shubham Garg

Reputation: 517

I see many detailed answers but I believe that writing just this line of code should be enough for the required task:

*{
    -webkit-user-select: none;
 }

Upvotes: 6

Tom Auger
Tom Auger

Reputation: 20111

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

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: Internet Explorer 9 may not need this extra jQuery piece, so you may want to add a version check in there.

Upvotes: 89

Santiago Cabrera
Santiago Cabrera

Reputation: 111

Add a class to your CSS that defines you cannot select or highlight an element. I have an example:

<style> 
    .no_highlighting{
        user-select: none;
    }

    .anchor_without_decoration:hover{
        text-decoration-style: none;
    }
</style>

<a href="#" class="anchor_without_decoration no_highlighting">Anchor text</a>

Upvotes: 9

Murtaza JAFARI
Murtaza JAFARI

Reputation: 734

This may work

    ::selection {
        color: none;
        background: none;
    }
    /* For Mozilla Firefox */
    ::-moz-selection {
        color: none;
        background: none;
    }

Upvotes: -2

GeekyMonkey
GeekyMonkey

Reputation: 12984

You may also want to prevent the context menu appearing when touching elements like buttons that have their selection prevented. To do that, add this code to the entire page, or just those button elements:

$("body").on("contextmenu",function(e){
    return false;
});

Upvotes: 0

codeWithMe
codeWithMe

Reputation: 892

It is 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>. You will have to 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 of course 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 text.

Upvotes: 28

Kaz
Kaz

Reputation: 1278

A Quick Hack Update

If you use the value none for all the CSS user-select properties (including browser prefixes of it), 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;     /* Internet Explorer  10+  */
     user-select: none;        /* Likely future           */
}

As CSS-Tricks says, the problem is:

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

You can also use the below one to enforce that an entire element gets selected which means if you click on an element, all the text wrapped in that element will get selected. For this all you have to do is changing the value none to all.

.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  */
}

Upvotes: 63

Alireza
Alireza

Reputation: 104840

You can use CSS or JavaScript for that.

The JavaScript way is supported in older browsers, like old versions of Internet Explorer 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>

Upvotes: 82

Chirag Dave
Chirag Dave

Reputation: 179

You can use a *-user-select property as below for that...

p {
    -webkit-user-select: none;  /* Chrome all and Safari all */
    -moz-user-select: none;     /* Firefox all */
    -ms-user-select: none;      /* Internet Explorer 10 and later */
    user-select: none;          /* Likely future */
}

Link for the Detailed Description

Upvotes: 11

user1012506
user1012506

Reputation: 2118

Try to insert these rows into the 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;
}

Upvotes: 64

Pushp Singh
Pushp Singh

Reputation: 606

This highlighting effect is due to the action called hover (onMouseHover).

When you will hover on any tab its color will be changed.

Just say for example,

HTML code

<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 use any color if you want to get it highlighted. Else you can use none.

Upvotes: 8

Mohammed Javed
Mohammed Javed

Reputation: 876

I have learned from the CSS-Tricks website.

user-select: none;

And this also:

::selection {
    background-color: transparent;
}

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

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

Upvotes: 21

mustafa-elhelbawy
mustafa-elhelbawy

Reputation: 530

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

Upvotes: 10

SemanticZen
SemanticZen

Reputation: 1151

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

Upvotes: 27

Beep.exe
Beep.exe

Reputation: 1398

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

Upvotes: 54

Suraj Naik
Suraj Naik

Reputation: 505

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

Upvotes: 20

Elad Shechter
Elad Shechter

Reputation: 4045

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; /* Internet Explorer  */
}

Upvotes: 68

Gaurang
Gaurang

Reputation: 1958

-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');

Upvotes: 50

Alex
Alex

Reputation: 939

Workaround for WebKit:

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

I found it in a CardFlip example.

Upvotes: 92

Tim Down
Tim Down

Reputation: 324627

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

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

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

For Internet Explorer < 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 rerun 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 (Internet Explorer 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.

Upvotes: 962

Gaurav Aggarwal
Gaurav Aggarwal

Reputation: 10187

Suppose there are two divs like this:

.second {
  cursor: default;
  user-select: none;
  -webkit-user-select: none;
  /* Chrome/Safari/Opera */
  -moz-user-select: none;
  /* Firefox */
  -ms-user-select: none;
  /* Internet Explorer/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 the user.

Prefix need to be used to support it in all browsers. Without a prefix this may not work in all the answers.

Upvotes: 37

ZECTBynmo
ZECTBynmo

Reputation: 3367

In the solutions in previous answers 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.

Upvotes: 144

Yevgeniy Afanasyev
Yevgeniy Afanasyev

Reputation: 41400

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

Upvotes: 5

grinmax
grinmax

Reputation: 1855

Maybe you can use this solution through :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/

Upvotes: 0

Pekka
Pekka

Reputation: 449613

A JavaScript solution for Internet Explorer is:

onselectstart="return false;"

Upvotes: 212

Related Questions