关于css:如何禁用文本选择突出显示?

How to disable text selection highlighting?

对于类似按钮(例如,问题、标签、用户等,位于堆栈溢出页顶部)或选项卡的锚,如果用户意外选择文本,是否有CSS标准方法禁用突出显示效果?

我意识到这可以用JavaScript来完成,并且稍微谷歌一下就产生了只支持Mozilla的-moz-user-select选项。

有没有一种符合标准的方法来用CSS来实现这一点,如果没有,那么"最佳实践"方法是什么?


更新日期:2017年1月:

根据can i use,目前除Internet Explorer 9和早期版本外,所有浏览器都支持user-select(但遗憾的是,仍然需要供应商前缀)。

所有正确的CSS变体都是:

1
2
3
4
5
6
7
8
9
.noselect {
  -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 */

}
1
2
3
4
5
6
7
8
9
<p>

  Selectable text.

</p>
<p class="noselect">
  Unselectable text.

</p>

请注意,它是一个非标准特性(即不是任何规范的一部分)。它不能保证在任何地方都能正常工作,浏览器之间的实现可能存在差异,将来浏览器可能会放弃对它的支持。

更多信息可以在Mozilla开发者网络文档中找到。


在大多数浏览器中,可以使用css user-select属性上的专有变体来实现这一点,最初在css3中提出,然后在css3中放弃,现在在css ui level 4中提出:

1
2
3
4
5
6
7
8
9
10
11
12
*.unselectable {
   -moz-user-select: 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;
}

对于ie<10和opera<15,需要使用希望不可选择的元素的EDOCX1[3]属性。您可以使用HTML中的属性设置:

1
...

遗憾的是,这个属性没有被继承,这意味着您必须在中的每个元素的开始标记中放置一个属性。如果这是一个问题,您可以使用javascript递归地为元素的后代执行此操作:

1
2
3
4
5
6
7
8
9
10
11
12
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"));

更新时间:2014年4月30日:每当有新元素添加到树中时,都需要重新运行此树遍历,但@han的评论似乎可以通过添加在事件目标上设置unselectablemousedown事件处理程序。有关详细信息,请参阅http://jsbin.com/yagekiji/1。

这仍然不能涵盖所有的可能性。虽然不可能在不可选择的元素中启动选择,但在某些浏览器(例如,IE和火狐)中,仍然不可能阻止在不可选择的元素之前开始和之后结束的选择,而不使整个文档不可选择。


IE的javascript解决方案是

1
onselectstart="return false;"


在CSS 3的用户选择属性可用之前,基于Gecko的浏览器支持您已经找到的-moz-user-select属性。webkit和基于blink的浏览器支持-webkit-user-select属性。

当然,在不使用Gecko呈现引擎的浏览器中不支持这一点。

没有"标准"兼容的快速简单的方法可以做到这一点;可以选择使用JavaScript。

真正的问题是,为什么您希望用户不能突出显示和复制粘贴某些元素?我从来没有遇到过这样的情况:我不想让用户在我的网站上突出显示某一部分。我的几个朋友在花了很多时间阅读和编写代码后,将使用突出显示功能来记住他们在页面上的位置,或者提供一个标记,以便他们的眼睛知道下一步要看哪里。

我能看到的唯一有用的地方是,如果用户复制并粘贴了网站,那么表单的按钮不应该被复制和粘贴。


如果要在除

元素外的所有元素上禁用文本选择,可以在css中执行此操作(注意-moz-none,它允许在子元素中进行覆盖,这在其他使用none的浏览器中是允许的):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
* {
    -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;
}


在上述解决方案中,选择停止,但用户仍然认为可以选择文本,因为光标仍在更改。要使其保持静态,必须设置CSS光标:

1
2
3
4
5
6
7
8
9
.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;
}
1
2
3
4
5
6
7
8
9
<p>

  Selectable text.

</p>
<p class="noselect">
  Unselectable text.

</p>

这将使您的文本完全平放,就像在桌面应用程序中一样。


你可以在Firefox和Safari中这样做(Chrome也是如此?)

1
2
::selection { background: transparent; }
::-moz-selection { background: transparent; }


WebKit的解决方法:

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

我在一个卡片的例子中找到了它。


我喜欢混合的css+jquery解决方案。

要使EDOCX1[0]内的所有元素不可选择,请使用此css:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.draggable {
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -o-user-select: none;
    -ms-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;
 }

然后,如果您使用jquery,请将其添加到$(document).ready()块中:

1
if (($.browser.msie && $.browser.version < 10) || $.browser.opera) $('.draggable').find(':not(input)').attr('unselectable', 'on');

我认为您仍然希望任何输入元素都是可交互的,因此使用:not()伪选择器。如果你不在乎的话,你可以用'*'来代替。

注意:IE9可能不需要这个额外的jquery条目,所以您可能需要在这里添加一个版本检查。


1
2
3
.hidden:after {
    content: attr(data-txt);
}
1
2
<p class="hidden" data-txt="Some text you don't want to be selected">
</p>

不过,这不是最好的办法。


您可以使用css或javascript来实现这一点,在旧的IE等浏览器中也支持javascript方式,但如果不是您的情况,请使用css方式:

HTML/javascript:

1
2
3
4
5
6
7
8
<html onselectstart='return false;'>
  <body>
    This is the Heading!
    <p>
And I'm the text, I won't be selected if you select me.
</p>
  </body>
</html>

HTML/CSS:

1
2
3
4
5
6
7
8
.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;
}
1
2
3
4
5
6
<body class="not-selectable">
  This is the Heading!
  <p>
And I'm the text, I won't be selected if you select me.
</p>
</body>


此外,对于Internet Explorer,还需要添加伪类焦点(.classname:focus)和大纲样式:none。

1
2
3
4
5
6
7
8
9
10
.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;/*IE*/
}


尝试将此行插入到CSS并在Class属性处调用"dishighlight":

1
2
3
4
5
6
7
8
.disHighlight{
    user-select: none;
    -webkit-user-select: none;
    -ms-user-select: none;
    -webkit-touch-callout: none;
    -o-user-select: none;
    -moz-user-select: none;
}


对于在Android浏览器中无法通过触摸事件实现相同功能的用户,请使用:

1
2
3
4
5
6
html,body{
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -webkit-tap-highlight-color: rgba(0,0,0,0);
    -webkit-tap-highlight-color: transparent;
}


1
2
3
4
5
6
7
8
9
10
11
12
-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;
}
1
...
1
2
3
4
5
6
7
8
9
10
11
12
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"));
1
2
-webkit-user-select:none;
-moz-user-select:none;
1
onselectstart="return false;"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
::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;
}
1
 

10

1
if ($.browser.msie) $('.draggable').find(':not(input)').attr('unselectable', 'on');

工作

CSS:

1
2
3
4
5
6
 -khtml-user-select: none;
 -moz-user-select: none;
 -ms-user-select: none;
  user-select: none;
 -webkit-touch-callout: none;
 -webkit-user-select: none;

这应该是可行的,但是对于旧的浏览器来说是行不通的。存在浏览器兼容性问题。


如果您使用较少的引导程序,可以编写:

1
.user-select(none);

除了mozilla-only属性之外,不,没有办法只使用标准的css来禁用文本选择(目前为止)。

如果您注意到,堆栈溢出不会禁用其导航按钮的文本选择,我建议在大多数情况下不要这样做,因为它会修改正常的选择行为并使其与用户的期望冲突。


这在某些浏览器中有效:

1
2
3
::selection{ background-color: transparent;}
::moz-selection{ background-color: transparent;}
::webkit-selection{ background-color: transparent;}

只需在选择器前面添加所需的元素/ID,用逗号分隔,不带空格,如下所示:

1
2
3
h1::selection,h2::selection,h3::selection,p::selection{ background-color: transparent;}
h1::moz-selection,h2::moz-selection,h3::moz-selection,p::moz-selection{ background-color: transparent;}
h1::webkit-selection,h2::webkit-selection,h3::webkit-selection,p::webkit-selection{ background-color: transparent;}

其他的答案更好;这可能被视为最后的手段。


假设有两个这样的分区

1
2
3
4
5
6
7
8
9
10
11
12
.second {
  cursor: default;
  user-select: none;
  -webkit-user-select: none;
  /* Chrome/Safari/Opera */
  -moz-user-select: none;
  /* Firefox */
  -ms-user-select: none;
  /* IE/Edge */
  -webkit-touch-callout: none;
  /* iOS Safari */
}
1
2
3
4
5
  This is my first div



  This is my second div

将光标设置为默认值,这样它将给用户一种不可选择的感觉。/

Prefix need to be use to support it in all browsers without prefix this may not work in all the answers.


如果不需要颜色选择,这将很有用:

1
2
::-moz-selection { background:none; color:none; }
::selection { background:none; color:none; }

…所有其他浏览器修复。它将在Internet Explorer 9或更高版本中工作。


将此添加到要在其中禁用文本选择的第一个分区:

1
2
onmousedown='return false;'
onselectstart='return false;'

注:

正确答案是正确的,因为它会阻止您选择文本。但是,这并不能阻止你复制文本,正如我将在接下来的几张截图中显示的(截至2014年11月7日)。

Before we have selected anything

After we have selected

The numbers have been copied

如您所见,我们无法选择号码,但我们可以复制它们。

测试地点:Ubuntu,Google Chrome 38.0.2125.111。


为了得到我需要的结果,我发现我必须同时使用::selectionuser-select

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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;
}


这不是CSS,但值得一提:

jquery用户界面禁用选择:

1
$("your.selector").disableSelection();


不使用javascript检查我的解决方案:

杰西德

1
2
3
4
5
6
7
8
9
10
11
12
li:hover {
    background-color: silver;
}
#id1:before {
    content:"File";
}
#id2:before {
    content:"Edit";
}
#id3:before {
    content:"View";
}
1
2
3
4
5
6
7
8
9
10
11
12
13
<ul>

   
<li>

   
<li>

   
<li>


</ul>

应用了我的技术的弹出菜单:http://jsfiddle.net/y4lac/2/


尽管这个伪元素是在3级CSS选择器的草稿中,但它在候选推荐阶段被删除了,因为它的行为似乎是未被指定的,特别是对于嵌套元素,并且没有实现互操作性。

这将在::selection如何处理嵌套元素中讨论。

尽管它正在浏览器中实现,但是您可以通过在选择时使用与选项卡设计(在您的情况下)相同的颜色和背景色来制造文本未被选择的假象。

普通CSS设计

1
p { color: white;  background: black; }

论选择

1
2
p::-moz-selection { color: white;  background: black; }
p::selection      { color: white;  background: black; }

不允许用户选择文本会导致可用性问题。


快速黑客更新:2017年3月-来自CSS技巧

如果将所有CSS用户选择属性的值设置为"无",如下面所示,则仍然会出现问题。

10

正如CSS技巧所说,问题在于:

  • 如果选择元素,WebKit仍允许复制文本在它周围。

因此,您也可以使用下面的方法来强制选择整个元素,这是解决问题的方法。您只需将值"none"更改为"all",如下所示:

1
2
3
4
5
6
.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 */  
}

我从CSS技巧网站上学习过。

1
user-select: none;

这也是:

1
2
3
::selection{ background-color: transparent;}
::moz-selection{ background-color: transparent;}
::webkit-selection{ background-color: transparent;}

轻松完成:

1
2
3
4
5
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;

可选地:

假设你有一个

Hello, World!,你要做的就是去掉h1的内部:在这种情况下,你好,世界。然后您必须转到CSS并执行以下操作:

1
2
3
4
5
6
#example::before //You can ofc 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.
}

现在它只是认为它是块元素,而不是文本。


此突出显示效果是由一个称为"悬停"(OnMouseOver)的操作引起的。当你将鼠标悬停在任何选项卡上时,它的颜色都会改变。比如说。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 <ul class="effect">
   
<li>
Questions
</li>

   
<li>
JOBS
</li>

   
<li>
Users
</li>

 
</ul>



<!-- CSS CODE -->

.effect:hover{
   color: none;
}

你可以给任何颜色,如果你想让它突出,否则你不能给任何颜色。


试着用这个:

1
2
3
::selection {
    background: transparent;
}

如果要指定不在特定元素内选择,只需将元素类或ID放在选择规则之前,例如:

1
2
3
4
5
6
.ClassNAME::selection {
    background: transparent;
}
#IdNAME::selection {
    background: transparent;
}

您可以使用用户选择属性,如下所示。

1
2
3
4
5
6
p {  
     -webkit-user-select: none;  /* Chrome all / Safari all */
     -moz-user-select: none;     /* Firefox all */
     -ms-user-select: none;      /* IE 10+ */
      user-select: none;          /* Likely future */            
   }

详细说明链接


如果要禁用整个页面的选择和突出显示,可以使用CSS轻松执行此操作:

1
2
3
4
5
6
7
8
9
* {
    -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 */

  }


1
2
3
4
 -webkit-user-select: none;  
  -moz-user-select: none;    
  -ms-user-select: none;      
  user-select: none;

用CSS—

1
2
3
4
5
6
7
8
9
10
div {
  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
  user-select: none;
  -o-user-select: none;

 "unselectable='on' onselectstart="return false;"
  onmousedown="
return false;
}
1
2
3
  Blabla
  <br/> More Blabla
  <br/> More Blabla...


更好的是,您可以禁用文本选择。

如果您喜欢SASS(SCSS),并且不想使用指南针,可以这样做:

styles.scss

1
2
3
4
5
6
7
8
9
10
11
@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);
}

我将各种浏览器css select属性与Internet Explorer<9所需的不可选择标记组合在一起。

1
2
3
4
5
6
7
8
9
<style>
[unselectable="on"] {
    -webkit-user-select: none; /* Safari */
    -moz-user-select: none; /* Firefox */
    -ms-user-select: none; /* Internet Explorer 10+/Edge */
    user-select: none; /* Standard */
}
</style>
Unselectable Text

也许你可以通过以下方式使用这个解决方案:之前

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<nav>
   
<ul>

   
<li>
Link
</li>

    <li class="disabled">Link
</li>

   
<li>
Link
</li>

   
</ul>

</nav>

jfiddle-https://jsfiddle.net/grinmax_uu9l1cckxu/


1
2
3
::selection {background: transparent; color: transparent;}

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