协慌网

登录 贡献 社区

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

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

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

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

答案

更新 2017 年 1 月:

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


所有正确的 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 Developer Network 文档中找到更多信息。

在大多数浏览器中,这可以使用 CSS user-select属性的专有变体来实现, 最初提出然后在 CSS3 中放弃 ,现在在CSS UI Level 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)中,仍然无法阻止在不可选元素之前和之后开始的选择而不会使整个文档无法选择。

IE 的 JavaScript 解决方案是

onselectstart="return false;"

2017 年 1 月更新:

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


所有正确的 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 开发人员网络文档中找到更多信息。

在大多数浏览器中,这可以通过使用 CSS user-select属性的专有变体来实现,该属性最初是在 CSS3 中提出,然后在 CSS3 中放弃 ,现在在CSS UI Level 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)中,仍然无法防止在不可选择的元素之前和之后开始的选择而不会使整个文档不可选择。

IE 的 JavaScript 解决方案是

onselectstart="return false;"