对于充当按钮(例如位于 Stack Overflow 页面顶部的问题、标签、用户等)或选项卡的锚点,如果用户不小心选择了文本,是否有 CSS 标准方法来禁用突出显示效果?
我意识到这可以通过 JavaScript 完成,并且通过谷歌搜索产生了仅 Mozilla 的 -moz-user-select
选项。
是否有一种符合标准的方式来使用 CSS 实现这一点,如果没有,“最佳实践”方法是什么?
::selection { background: transparent; } ::-moz-selection { background: transparent; }
postcss
和 autoprefixer
并设置浏览器版本,然后 postcss
让一切变得凉爽。
2017 年 1 月更新:
根据 Can I use,目前所有浏览器都支持 user-select
,除了 Internet Explorer 9 及其早期版本(但遗憾的是仍然需要供应商前缀)。
这些是所有可用的正确 CSS 变体:
.noselect { -webkit-touch-callout:无; /* 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 */ 用户选择:无; /* 无前缀版本,目前支持 Chrome、Edge、Opera 和 Firefox */ }
可选文本。
不可选择的文本。
请注意,user-select
处于标准化过程中(当前处于 W3C working draft 中)。它不能保证在任何地方都可以工作,并且浏览器之间的实现可能存在差异。此外,浏览器将来可能会放弃对它的支持。
更多信息可在 Mozilla Developer Network documentation 中找到。
此属性的值为 none
、text
、toggle
、element
、elements
、all
和 inherit
。
在大多数浏览器中,这可以使用 CSS user-select
属性 originally proposed and then abandoned in CSS 3 的专有变体来实现,现在在 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;
}
对于 Internet Explorer < 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 的评论看来,可以通过添加 {2 } 在事件目标上设置 unselectable
的事件处理程序。有关详细信息,请参阅 http://jsbin.com/yagekiji/1。
这仍然没有涵盖所有可能性。虽然不可能在不可选择的元素中启动选择,但在某些浏览器(例如 Internet Explorer 和 Firefox)中,仍然不可能阻止在不可选择元素之前和之后开始的选择而不使整个文档不可选择。
*.foo
和 .foo
是完全等价的(在第二种情况下,通用选择器 (*
) 是隐含的),所以除非浏览器怪癖,我看不出包含 *
会损害性能。包含 *
是我的一个长期习惯,我最初是为了可读性而开始这样做的:它一目了然地明确指出作者打算匹配所有元素。
在 CSS 3 的 user-select 属性可用之前,基于 Gecko 的浏览器支持您已经找到的 -moz-user-select
属性。 WebKit 和基于 Blink 的浏览器支持 -webkit-user-select
属性。
这在不使用 Gecko 渲染引擎的浏览器中当然是不支持的。
没有符合“标准”的快速简便的方法来做到这一点;使用 JavaScript 是一种选择。
真正的问题是,为什么您希望用户不能突出显示并可能复制和粘贴某些元素?我从来没有遇到过我不想让用户突出显示我网站的某个部分的情况。我的几个朋友在花了很多时间阅读和编写代码之后,会使用高亮功能来记住他们在页面上的位置,或者提供一个标记,以便他们的眼睛知道下一步该往哪里看。
我认为这很有用的唯一地方是,如果用户复制和粘贴网站时,如果您有不应该复制和粘贴的表单按钮。
Internet Explorer 的 JavaScript 解决方案是:
onselectstart="return false;"
ondragstart
!
如果您想禁用除 <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;
}
p, input { -webkit-user-select: text; -khtml-user-select: text; -moz-user-select: text; -o-user-select: text; user-select: text; }
-moz-none
和 none
是相同的。
ul>* { -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: -moz-none; -o-user-select: none; user-select: none; }
[选择无序列表中的所有内容,并使其不可选择,而不是破坏整个视图树。] 感谢您的课程。我的按钮列表看起来很棒,并且可以正确响应屏幕点击和按下,而不是启动 IME(android 剪贴板小部件)。
在先前答案中的解决方案中,选择已停止,但用户仍然认为您可以选择文本,因为光标仍在更改。为了保持静态,你必须设置你的 CSS 光标:
.noselect { 光标:默认; -webkit-touch-callout:无; -webkit 用户选择:无; -khtml-用户选择:无; -moz 用户选择:无; -ms 用户选择:无;用户选择:无; }
可选择的文本。
不可选择的文本。
这将使您的文本完全平坦,就像在桌面应用程序中一样。
user-select: none;
,以为该标准现在会被采用,但遗憾的是它没有。让你想知道标准委员会的人还在争论什么。 “不,你们……我真的认为应该是 user-select: cant;
,因为它更像是描述性的,你知道吗?” “我们已经解决了这个问题,迈克。我们将不得不省略撇号,这是一种糟糕的形式!” “够了,大家!这件事我们下个月再商议。标准委员会会议休会!”
您可以在 Firefox 和 Safari(Chrome 也可以?)
::selection { background: transparent; }
::-moz-selection { background: transparent; }
WebKit 的解决方法:
/* Disable tap highlighting */
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
我在 CardFlip 示例中找到了它。
transparent
代替 rgba 也适用于 Android 上的 Chrome 42。
我喜欢混合 CSS + jQuery 解决方案。
要使 <div class="draggable"></div>
内的所有元素不可选择,请使用以下 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;
}
然后,如果您使用的是 jQuery,请将其添加到 $(document).ready()
块中:
if (($.browser.msie && $.browser.version < 10) || $.browser.opera) $('.draggable').find(':not(input)').attr('unselectable', 'on');
我认为您仍然希望任何输入元素都是可交互的,因此 :not()
伪选择器。如果您不在乎,可以改用 '*'
。
警告:Internet Explorer 9 可能不需要这个额外的 jQuery 片段,因此您可能需要在其中添加版本检查。
-moz-user-select: Normal;
jQuery.browser
自 1.3 版起已弃用,并已在 1.9 版中删除 - api.jquery.com/jQuery.browser
.hidden:after { 内容:attr(data-txt); }
不过,这不是最好的方法。
title
作为属性。
user-select
的。
您可以为此使用 CSS 或 JavaScript。
旧版浏览器也支持 JavaScript 方式,例如旧版本的 Internet Explorer,但如果不是您的情况,请使用 CSS 方式:
HTML/JavaScript:
而且我是文字,如果你选择我,我不会被选中。
HTML/CSS:
.not-selectable { -webkit-touch-callout: none; -webkit 用户选择:无; -khtml-用户选择:无; -moz 用户选择:无; -ms 用户选择:无;用户选择:无; }
而我是文字,你选择我就不会被选中。
身体>
另外对于 Internet Explorer,您需要添加 伪类 focus
(.ClassName:focus) 和 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 */
}
className
类的元素开始,这在 IE 中确实有效。请参阅此JSBin。
尝试将这些行插入 CSS 并在类属性中调用“disHighlight”:
.disHighlight {
user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-webkit-touch-callout: none;
-o-user-select: none;
-moz-user-select: none;
}
快速破解更新
如果您对所有 CSS user-select
属性(包括它的浏览器前缀)使用值 none
,则仍然会出现问题。
.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 */
}
正如 CSS-Tricks 所说,问题是:
WebKit 仍然允许复制文本,如果您选择它周围的元素。
您还可以使用下面的 enforce
来选择整个元素,这意味着如果您单击一个元素,则包含在该元素中的所有文本都将被选中。为此,您只需将值 none
更改为 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 */
}
使用 SASS(SCSS 语法)
您可以使用 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;
}
在 HTML 标记中:
<div class="no-selectable">TRY TO HIGHLIGHT. YOU CANNOT!</div>
在这个CodePen中试试。
如果您使用的是 autoprefixer,则可以删除其他前缀。
浏览器兼容性 here。
对于那些在 Android 浏览器中无法通过触摸事件实现相同功能的用户,请使用:
html, body {
-webkit-touch-callout: none;
-webkit-user-select: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-tap-highlight-color: transparent;
}
-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');
除了 Mozilla-only 属性,不,没有办法仅使用标准 CSS 禁用文本选择(截至目前)。
如果您注意到,Stack Overflow 不会禁用其导航按钮的文本选择,我建议在大多数情况下不要这样做,因为它会修改正常的选择行为并使其与用户的期望相冲突。
这适用于某些浏览器:
::selection{ background-color: transparent;}
::moz-selection{ background-color: transparent;}
::webkit-selection{ background-color: transparent;}
只需在选择器前面添加您想要的元素/id,用逗号分隔,不带空格,如下所示:
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;}
其他答案更好;这可能应该被视为最后的手段/总括。
假设有两个这样的 div
:
.second { 光标:默认;用户选择:无; -webkit 用户选择:无; /* Chrome/Safari/Opera */ -moz-user-select: none; /* Firefox */ -ms-user-select: none; /* Internet Explorer/Edge */ -webkit-touch-callout: none; /* iOS Safari */ }
将光标设置为默认值,这样它会给用户一种无法选择的感觉。
需要使用前缀在所有浏览器中支持它。如果没有前缀,这可能不适用于所有答案。
如果也不需要颜色选择,这将很有用:
::-moz-selection { background:none; color:none; }
::selection { background:none; color:none; }
...所有其他浏览器修复。它将在 Internet Explorer 9 或更高版本中工作。
color: inherit;
也许。
将此添加到要禁用文本选择的第一个 div:
onmousedown='return false;'
onselectstart='return false;'
笔记:
正确答案是正确的,因为它会阻止您选择文本。但是,它不会阻止您复制文本,正如我将在接下来的几个屏幕截图中展示的那样(截至 2014 年 11 月 7 日)。
https://i.stack.imgur.com/gcKTY.png
https://i.stack.imgur.com/xwPld.png
https://i.stack.imgur.com/Ex6UH.png
如您所见,我们无法选择数字,但我们能够复制它们。
测试于:Ubuntu、Google Chrome 38.0.2125.111。
它很容易通过以下方式完成:
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
或者:
假设您有一个 <h1 id="example">Hello, World!</h1>
。您必须删除该 h1
的 innerHTML,在本例中为 Hello, World。然后你将不得不去 CSS 并这样做:
#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.
}
现在它只是认为它是一个块元素,而不是文本。
为了得到我需要的结果,我发现我必须同时使用 ::selection
和 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;
}
在没有 JavaScript 的情况下检查我的解决方案:
li:hover { 背景颜色:银色; } #id1:before { 内容:“文件”; } #id2:before { 内容:“编辑”; } #id3:before { 内容:“查看”; }
应用了我的技术的弹出菜单:http://jsfiddle.net/y4Lac/2/
虽然这个伪元素出现在 CSS 选择器 Level 3 的草案中,但在候选推荐阶段被删除了,因为它的行为似乎没有明确说明,尤其是嵌套元素,并且没有实现互操作性。
How ::selection works on nested elements 中正在讨论它。
尽管它正在浏览器中实现,但您可以通过在选择时使用与选项卡设计相同的颜色和背景颜色(在您的情况下)来制造未选择文本的错觉。
普通 CSS 设计
p { color: white; background: black; }
选择时
p::-moz-selection { color: white; background: black; }
p::selection { color: white; background: black; }
不允许用户选择文本会引发可用性问题。
我从 CSS-Tricks 网站了解到。
user-select: none;
这也是:
::selection {
background-color: transparent;
}
::moz-selection {
background-color: transparent;
}
::webkit-selection {
background-color: transparent;
}
不定期副业成功案例分享
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;
。啊,好多了。-webkit-user-select: none;
行。