题 如何禁用文本选择突出显示?


对于像按钮一样的锚点(例如, 问题标签用户等,在Stack Overflow页面的顶部)或标签,是否有一种CSS标准方法来禁用突出显示效果,如果用户意外选择文本?

我意识到这可以通过JavaScript来完成,并且有点谷歌搜索产生了仅Mozilla -moz-user-select 选项。

是否有符合标准的方法来实现CSS,如果没有,什么是“最佳实践”方法?


4360
2018-05-05 20:29


起源


元素中的元素是否已突出显示禁用,在样式或类属性中使用css启用突出显示?或换句话说,是否有-webkit-user-select等的其他值。除了没有?
'user-select'-值:无|文字|切换|元素|元素|所有|继承 - w3.org/TR/2000/WD-css3-userint-20000216 - Blowsie
uihacker.blogspot.com/2011/12/... - Enve
有关: stackoverflow.com/questions/16600479/... =如何只允许选择一些子元素 - JK.
某些浏览器中存在一个错误,即“全选”(CTRL + A和CMD + A)仍会选择内容。这可以用透明的选择颜色进行: ::selection { background: transparent; } ::-moz-selection { background: transparent; } - DaAwesomeP


答案:


更新2017年1月:

根据 我可以用吗user-select 目前在除Internet Explorer 9和早期版本之外的所有浏览器中都受支持(但遗憾的是 仍然 需要供应商前缀)。


所有正确的CSS变体都是:

.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 */
}
<p>
  Selectable text.
</p>
<p class="noselect">
  Unselectable text.
</p>


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


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


6369
2017-12-05 11:45



很好的代码molokoloco:D,虽然我个人会远离使用它,因为有时您可能需要不同的浏览器不同的值,它依赖于JavaScript。创建一个类并将其添加到元素中或将css应用于样式表中的元素类型是非常有效的。 - Blowsie
'user-select'-值:无|文字|切换|元素|元素|所有|继承 - w3.org/TR/2000/WD-css3-userint-20000216 - Blowsie
实际上在Opera中没有实现-o-user-select。它实现了IE的不可选属性。 - Tim Down
出于某种原因,仅此一点在IE8中工作,我接着补充道 <div onselectstart="return false;"> 到我的主要部门。 - robasta
这是荒唐的!有很多不同的方法来做同样的事情。让我们为用户选择制定新标准。我们会称之为 standard-user-select。那我们就不会有这些问题。虽然为了向后兼容,我们也应该包括其他的。所以现在代码变成了 -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; standard-user-select: none;。啊,好多了。 - Claudiu


在大多数浏览器中,这可以使用CSS上的专有变体来实现 user-select 属性, 最初提出然后放弃在CSS3中 现在提出来了 CSS UI级别4

*.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,您将需要使用 unselectable 您希望不可选择的元素的属性。您可以使用HTML中的属性来设置它:

<div id="foo" unselectable="on" class="unselectable">...</div>

遗憾的是,这个属性不是继承的,这意味着你必须在一个内部的每个元素的开始标记中放置一个属性 <div>。如果这是一个问题,您可以使用JavaScript以递归方式为元素的后代执行此操作:

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的注释似乎可以避免这种情况。 添加一个 mousedown 设置的事件处理程序 unselectable 关于事件的目标。看到 http://jsbin.com/yagekiji/1 详情。


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


727
2017-11-13 16:05



你应该从你的例子中删除*选择器,它真的没有效率,并且真的没有需要在你的例子中使用它吗? - Blowsie
@Blowsie:我不这么认为:CSS 2规范说明了这一点 *.foo 和 .foo 是完全等价的(在第二种情况下,通用选择器(*)暗示),所以禁止浏览器怪癖,我看不出包括 * 会伤害表现。我的长期习惯包括 *,我最初开始做的是为了可读性:它明确地说明作者打算匹配所有元素。 - Tim Down
经过一些进一步的阅读后,似乎*只是在使用它作为关键词(最右边的选择器)时才是无效的,即。不可选择*。更多信息在这里 code.google.com/speed/page-speed/docs/... - Blowsie
而不是使用class =“unselectable”,只需使用属性选择器[unselectable =“on”] {...} - Chris Calo
@Francisc:没有。正如我在评论中早些时候对Blowsie所说的那样,它确实没有区别。 - Tim Down


IE的JavaScript解决方案是

onselectstart="return false;"

165
2018-05-05 20:37



别忘了 ondragstart! - Mathias Bynens
还有一件事。如果将其添加到正文中,则无法在textareas中选择文本或在IE中输入字段。我为IE修复它的方式。 body.onselectstart = function(e) { if (e.target.nodeName != "INPUT" && e.target.nodeName != "TEXTAREA") { e.preventDefault(); return false; } return true; } - TheBrain
这可以使用jQuery添加为属性 - $(“p”)。attr(“onselectstart”,“return false”)这是我在IE8中唯一可靠的方法 - Matt
为什么我有多个css解决方案时使用javascript! - Abudayah
@Abudayah因为它们不适用于旧版本的Internet Explorer?就像这个答案的全部要点一样。 - Pekka 웃


直到CSS 3 用户选择 物业变得可用, 壁虎基于浏览器的支持 -moz-user-select 你已经找到的财产​​。 WebKit的 和基于Blink的浏览器支持 -webkit-user-select 属性。

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

没有符合“标准”的快速简便方法;使用JavaScript是一种选择。

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

我唯一能看到它有用的地方是,如果用户复制并粘贴网站,则表格的按钮不应复制和粘贴。


159
2018-05-24 21:24



按钮的东西正是我的动力。 - Kriem
需要的另一个原因是按住Shift键单击以选择网格或表格中的多个行。您不想突出显示文本,您希望它选择行。 - Gordon Tucker
还存在法律问题,其他人的内容正在合法重新发布,但许可中的条款要求网络发布者阻止文本被轻易复制和粘贴。这就是我找到这个问题的原因。我不同意这个要求,但我签约的公司在法律上有义务以这种方式实施。 - Craig M
@CraigM css样式不会阻止某人抓取HTML源并复制它。如果您想保护自己的内容,就必须找到更好的方法。 - Agile Jedi
高度互动的网络应用程序,拖放很多......意外突出显示是一个很大的可用性问题。 - Marc Hughes


如果要禁用除on之外的所有内容的文本选择 <p> 元素,你可以在CSS中做到这一点(注意 -moz-none 允许在子元素中覆盖,这在其他浏览器中是允许的 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;
}

120
2017-08-30 18:32



确保您还可以选择输入字段: p, input { -webkit-user-select: text; -khtml-user-select: text; -moz-user-select: text; -o-user-select: text; user-select: text; } - joshuadelange
关于除了一个项目之外的所有代码关闭浏览器UI期望时要非常谨慎。例如,列表项<li />文本怎么样? - Jason T Featheringham
只是一个更新...根据MDN自Firefox 21以来 -moz-none 和 none 是相同的。 - Kevin Fegan
为此你可以分别添加cursor:default和cursor:text:) - T4NK3R
精彩!它的工作原理谢谢! - Nam Nguyen


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

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

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


111
2018-05-05 20:46



“平”而不是什么? - kojow7


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

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

101
2017-09-21 07:09



我不建议这样做,因为它实际上并没有解决问题;禁用文本选择 - 它只是隐藏它。这可能会导致可用性不佳,因为如果我将光标拖到页面上,我可能会在不知情的情况下选择任意文本。这可能会导致各种奇怪的可用性“错误”。 - Keithamus
对于带有透明区域的PNG图像不起作用:将始终选择浅蓝色...任何解决方法? - AvL


解决方法 WebKit的

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

我在CardFlip示例中找到了它。


73
2017-11-11 19:53



运用 transparent 代替rgba也适用于Android上的Chrome 42。 - Clint Pachl


我喜欢混合CSS + jQuery解决方案。

使所有元素都在里面 <div class="draggable"></div> 不可选择,使用这个CSS:

.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() 块:

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

我想你仍然希望任何输入元素可以互动,因此 :not() 伪选择。你可以用 '*' 相反,如果你不在乎。

警告:IE9可能不需要这个额外的jQuery片段,所以你可能想在那里添加一个版本检查。


66
2018-05-01 11:36



使用-ms-user-select:none; (对于IE10)和你的jQuery“if”应该是这样的:if(($ .browser.msie && $ .browser.version <10)|| $ .browser.opera) - mhenry1384
小心的人!!!要在firefox中选择它,你必须使用 -moz-user-select: Normal; - Nicolas Thery
@nicholasthery w3.org/TR/2000/WD-css3-userint-20000216#user-select - Tom Auger
@ mhenry1384 jQuery.browser 自版本1.3起已被弃用,并已在版本1.9中删除 - api.jquery.com/jQuery.browser - WynandB
@Wynand好点。但是存在哪种“特征检测”来确定要使用哪个CSS属性? - Tom Auger


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

不过,这不是最好的方式。


62
2017-12-23 14:05



你也可以使用 title 作为属性。 - Toothbrush
这是一个非常有创意的解决方案特别是如果它使用title属性,因为这可能对屏幕阅读器更好。 - pseudosavant
我尝试过这个 (JSBin)它在IE中不起作用。不幸的是,旧的IE是唯一的 user-select 不起作用。 - pseudosavant