How to disable text selection highlighting
For anchors that act like buttons (for example Questions, Tags, Users, etc. which are located on the top of the Stack Overflow page) 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?
UPDATE January, 2017:
According to Can I use, the user-select
is currently supported in all browsers except Internet Explorer 9 and its earlier versions (but sadly still needs a vendor prefix).
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
.
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.
Until CSS 3's user-select property becomes available, Gecko-based browsers support the -moz-user-select
property you already found. WebKit and Blink-based browsers support the -webkit-user-select
property.
This of course is not supported in browsers that do not use the Gecko rendering engine.
There is no "standards" compliant quick-and-easy way to do it; using JavaScript is an option.
The real question is, why do you want users to not be able to highlight and presumably copy and paste certain elements? I have not come across a single time that I wanted to not let users highlight a certain portion of my website. Several of my friends, after spending many hours reading and writing code will use the highlight feature as a way to remember where on the page they were, or providing a marker so that their eyes know where to look next.
The only place I could see this being useful is if you have buttons for forms that should not be copy and pasted if a user copy and pasted the website.
A JavaScript solution for Internet Explorer is:
onselectstart="return false;"
If you want to disable text selection on everything except on <p>
elements, you can do this in CSS (watch out for the -moz-none
which allows override in sub-elements, which is allowed in other browsers with none
):
* {
-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;
}