您是否曾经看到(或将自己)一些文本放入一个 <textarea>
或 <input>
中,不是因为它属于表单的一部分,而是因为它使得整个文本块更容易选择。 这样的输入具有选择边界,这意味着您可以单击它们并(例如)全部选择并仅获取输入内的文本。
有一个 CSS 属性允许我们做到这一点,而无需使用不那么语义合适的表单输入。
它是 user-select
属性,它按以下方式工作
.force-select-all {
user-select: all;
}
Autoprefixer 会为您处理此操作,但如果手动操作,您需要以下内容才能获得最佳浏览器支持
.force-select-all {
-webkit-user-select: all; /* Covers Blink-land & Firefox (yup) */
user-select: all; /* Someday */
}
您问的示例?
我发现这种东西最常见的用例是“这里有一些服务器生成的、可复制粘贴的用于我们产品™的嵌入代码”。 想象一下 YouTube 或 Vimeo 视频的嵌入代码

在我以前那个 HTML-Ipsum 这样的网站上,它非常有意义,它急需更新。
一个演示
如何使用稍微不同的用例,比如一张备忘单,其中包含一些旨在复制的简单代码片段
查看 Pen SVG 形状备忘单 (user-select: all; 演示) by Chris Coyier (@chriscoyier) on CodePen.
关于前缀的更多信息
实际上,Autoprefixer 会为您提供
.force-select-all {
-webkit-user-select: all;
-moz-user-select: all;
-ms-user-select: all;
user-select: all;
}
这是可以理解的,因为
- 只为 Firefox 放入
-webkit-
很奇怪,即使它接受它 - Edge 不支持
all
,但它支持带有前缀的none
,因此它始终为该属性添加前缀
假设您不喜欢强制选择,但喜欢选择边界。
这就是 contain 值的意义所在。 它使文本选择的行为像在输入框中一样
.select-text-like-you-would-within-a-textarea {
/* Not supported anywhere yet */
user-select: contain;
}
唉,还没有支持。 不过 IE/Edge 支持一个专有版本
.ie-version-of-contain {
-ms-user-select: element;
}
所以现在我们有了 none
、all
和 contain
。 还有 text
,它使文本像“普通”文本一样可选。
如果您需要重置值,您应该使用 auto
,因为它是将元素恢复到其正常状态的值(例如,<p>
将恢复到文本,<textarea>
将恢复到 contain)。
样式化选定文本
由于我们在这里讨论的是选择文本,请记住您可以设置选定文本的样式
::-moz-selection { background: yellow; }
::selection { background: yellow; }
尽管……我可能建议不要将它们配对,因为自动选择文本行为已经很奇怪了,因此再加上完全不同的选择样式可能会让用户搞不清发生了什么。
或者至少,将 ::selection
设置为全局范围,而不是针对孤立区域。
经典的 JavaScript 方法
Edge 的不支持可能是您的一大障碍。 如果自动选择文本至关重要,您可能想坚持使用输入和 JavaScript。
超基本的示例
查看 Pen 最简单的选择 by Chris Coyier (@chriscoyier) on CodePen.
我相信您可以做得更花哨,例如,避免使用内联事件处理程序,并考虑“好吧,我已经点击了您,您选择了您的文本,我知道了,现在停止这样做,这样我才能只选择您的一部分”——这当然是可以做到的。
伪元素
无论好坏,user-select: text;
可能是使伪元素(如 ::before
或 ::after
)可选的一种方式,而它们目前在任何浏览器中都不可选。 您无法选择它们可能是一件好事,因为伪元素也不应该在 AT 中读取(因为它们不是“内容”)。 但在屏幕上看到无法选择的文本有点奇怪,所以我不会对浏览器在这方面做出任何决定感到惊讶。
移动设备
对于 iOS,您可能还想使用另一种方法
.prevent-touch-callout {
-webkit-touch-callout: none;
}
它不是专门针对选择,但如果您阻止选择文本,您可能也会阻止一般的交互。 MDN
当在 iPhone OS 上触摸并按住目标时,Safari 会显示有关链接的调用信息。 该属性允许禁用该行为。
强制复制?
既然我们讨论的是强制选择文本,我们也可以强制复制到剪贴板吗? 事实上,您可以做到。 以前有一种基于 Flash 的方法可以做到这一点,但正如我们都知道的那样,Flash 已经寿终正寝了。 Chrome 刚刚宣布了 另一项致命打击。 IE 10 支持这个 execCommand
东西,而且碰巧的是,这似乎是浏览器要使用的东西。 我从 Matt Gaunt 撰写的 Google 文章中抢到了这个演示
查看 Pen 使用按钮复制文本 (Google 示例) by Chris Coyier (@chriscoyier) on CodePen.
看起来在 Blink 世界、Firefox 和 Edge 中都能正常工作,所以……太棒了。
更多信息
- MDN 上的 user-select——更多关于前缀和专有值的详细信息。
- Can I Use 对支持情况的调查——特别是对 none 值的支持情况
- 规范的当前版本——据我所知,这是最好的版本
- Google 的文档,其中包含一些关于支持情况和指向相关错误的链接的有趣细节。
Whew
说这么多话只是为了一个简单的道理。团队很棒。
我认为你埋没了重点!对非 flash c&p 感到兴奋。
请不要这样做。这真的很烦人。如果你想“帮助”你的用户,只需要做一个复制按钮之类的东西。
我不想专门点名你,但我经常看到这种教条式的回应。在网络上唯一合适的“永远不要这样做”是“永远不要说永远不要这样做”。
没关系。我个人觉得它很烦人,我个人希望人们永远不要这样做。我想不出任何用例,其中覆盖预期的选择交互比正常交互更好,但我乐于接受完全错误的可能性。我只是认为强迫用户以某种方式交互有点自以为是,因为几乎不可能想到用户选择文本的所有原因。这就是我认为按钮可能是处理它的最佳方式的原因。它是完全可选的。
我同意这一点。我经常想从 YouTube 或 Vimeo 等网站的视频中获取嵌入 URL,以便将其放入 CMS 字段中。因为我无法只选择它的一部分,所以我最终不得不将其粘贴到文本编辑器中才能进行操作。
按钮的想法效果很好,据我所知,它会更加明确。单击此处复制,或者如果您只需要一部分,则此处是文本。
我必须同意 Tegan 和 Adam 的观点,至少在涉及
user-select: all
方面。我无法想到任何情况,在这些情况下你可以 100% 确定用户希望选择所有内容,而不是只选择一部分。当有人分享一些代码并要求你选择整个代码块时,而你只需要从中获取一个 URL 或其他东西,这非常令人恼火。
我将把自己加入不喜欢自动(不可避免)选择整个文本的人的行列。我经常发现自己只想复制文本的一部分,结果却发现自己说:“好吧,好吧,我把它粘贴到文本编辑器中,然后复制我想要的内容!”
强制选择整个内容会破坏用户预期行为,所以从 UX 的角度来看,我坚决反对。
是的,在 Google 地图中,我经常只需要代码的特定部分,但它总是强迫我复制整个嵌入代码,因此我必须将其粘贴到文本编辑器中,然后提取我需要的部分。
那么,
user-select: all
显然在 Chrome 中不起作用?我刚在 FF 中尝试了你的演示,效果很好,该行被突出显示为选中状态。Chrome 则什么都没有。我在 Windows 上,这会导致差异吗?我同意。我在 Chrome 52 中没有看到它起作用。
这里也是一样。对此感到失望,因为它看起来像一个真正的技巧,而且可能很有用。
可能是标志问题?
chrome://flags/
至少在 Chrome 52 中,当
about:flags/#enable-experimental-web-platform-features
处于开启状态时,它可以正常工作,并且在 Chrome 54 Canary 中没有使用任何标志时,它也可以正常工作。是的,标志确实起作用了!但这有点令人沮丧。:(
您好。此示例 http://codepen.io/chriscoyier/pen/dXKxvv 在 Chrome 52.0.2743.116 (64 位) 中不起作用。
如上所述(但在你的评论之后,我相信),
chrome://flags/
> 实验性 Web 平台功能或about:flags/#enable-experimental-web-platform-features
将在 Chrome 52 中启用它。我个人发现,我经常对此感到恼火,因为我试图选择一个特定部分,但它不起作用。我不知道这是否是普遍现象,但我想知道是否应该在鼠标按下 -> 鼠标拖动时禁用它,而只让它在单击时起作用?
另一个问题是,我永远不知道这是否会成为一个功能,而且经常只有在我完成选择的一半时才会发现,然后它出现了意想不到的行为。你认为我们是否有办法向用户表明该功能处于活动状态?
我喜欢检查他们是否正在选择部分的想法。我认为对于大多数我将使用它的场合,可以在选择后显示一个小的弹出窗口,提供选择所有选项。
哇,不!现在所有最好的屏幕阅读器都可以读取伪元素内容。作为 Web 开发人员,你不应该在伪元素中放置重要内容,因为有些屏幕阅读器无法读取它。但也不要认为它不会被读取。
(此外,关于帖子主题。我不喜欢强制“全部”选择的想法,但我可以接受单击选择,并且我绝对喜欢能够为全选重新创建文本输入式“包含”行为的想法。浏览器,继续支持该选项,好吗?)
谢谢你,Amelia。我正准备发布相同的内容——大多数当前的屏幕阅读器都可以读取 CSS 生成的内容(它不应作为隐藏内容的工具)。
至于文本选择,如果你作为作者明确表明将选择整个文本块,并且它在语境上是合适的,我认为这没问题。我也讨厌尝试选择某一部分,却总是选择整个内容。
此外,在这个评论表单中,字段有标签而不是只使用占位符,有没有可能?我不得不删除我的电子邮件地址以确保它没有要求 URL 而不是电子邮件地址。
我原以为一些屏幕阅读器(如 Voice Over)可以读取生成的文本,但不应该读取,因此始终存在停止读取的风险。我想它朝着另一个方向发展了。
Chris,它正朝着另一个方向发展。一年前,Léonie Watson 追踪了屏幕阅读器对生成内容的支持,并表明它得到了很好的支持。从那时起,支持一直在增加/改善。原因是许多作者使用生成的内容来完成装饰之外的事情,因此 AT 必须开始读取它。