CSS中的選擇( ::selection和user-select)
在網絡上,我們出於不同原因選擇內容,也許我們想復制文本並在某處引用它。對於移動端來說,選擇內容比較難,我不喜歡在移動端選擇內容。
在本文中,我將詳細介紹CSS中有關選擇的所有內容,包括偽類 ::selection 和 user-select。本文的目標是讓你了解所有這些技術,並讓你知道何時何地使用它們。
根據Mozilla開發人員網絡(MDN):
::selection CSS偽元素將樣式應用於用戶已突出顯示的文檔部分(例如,在文本上單擊並拖動鼠標)。
要使用 ::selection 偽類,只需執行以下操作:
p::selection {
color: #fff;
background-color: #000;
}

::selection支持的屬性
值得注意的是 ::selection 僅支持 color,background 和 text-shadow 屬性。
自定義選擇
如果我們想要自定義選擇效果怎么辦?例如,控制選擇的高度並具有自定義背景?見下圖:

這是可能的,但有點棘手。下面是如何做到這一點的解釋:
- 我們添加具有相同文本內容的偽元素。然后,我們給它一個50%的高度,並帶有白色背景色。
- 偽元素位於原始文本上方。
現在,選擇文本后,偽元素將垂直覆蓋文本的50%。這模仿了我們所需的效果。
p {
position: relative;
color: #fff;
}
p:after {
content: attr(data-content);
position: absolute;
color: #000;
top: 0;
left: 0;
width: 100%;
height: 50%;
background-color: #fff;
}
p::selection {
background: rgba(76, 125, 225, 0.18);
}
作為另一種選擇,我對上述內容進行了調整,而改用CSS漸變。這里的重點是使用白色漸變,高度為50%,並且不重復背景。
h1:after {
content: attr(data-content);
position: absolute;
color: #000;
top: 0;
left: 0;
width: 100%;
background: linear-gradient(#fff, #fff) top/100% 50% no-repeat;
}
請參見下圖,以獲得直觀的說明。

希望現在更加清楚!請參閱CodePen上的demo。
Demo:https://codepen.io/shadeed/pen/5074964e902cd83d96e5ce7ba9ee1423?editors=1100
動畫選擇
在進行上一個演示時,我問自己一個問題:是否可以對選擇進行動畫處理?例如,當選擇文本並且鼠標沒有懸停時,高度為50%,而當鼠標懸停時,高度可以增加到80%。
p {
transition: background 0.3s ease-out;
}
p:hover:after {
background-size: 100% 80%;
}

多行文字
不幸的是,上述解決方案不適用於多行文字。為了使其工作,我們應該使用JavaScript將每個單詞包裝在一個內聯元素(例如<span>)中。一旦每個字都在 <span> 元素中,就應該給每個字添加一個偽元素,也可以使用同樣的技術。
請參閱以下腳本,將每個單詞包裝在 <span> 元素中。
let paragraph = document.querySelector(".text");
const words = paragraph.textContent.split(" ");
paragraph.innerHTML = "";
words.forEach(function (word) {
let wordItem = document.createElement("span");
wordItem.setAttribute("data-word", word);
wordItem.innerHTML = word + " ";
paragraph.appendChild(wordItem);
});
現在,你需要為每個 <span> 元素設置樣式,然后為每個元素添加一個偽元素。
span {
position: relative;
font-size: 1.25rem;
line-height: 1.4;
}
span::after {
content: attr(data-word);
position: absolute;
left: 0;
right: 0;
top: -0.28em;
height: 75%;
padding-top: 0.14em;
background: #fff;
pointer-events: none;
}
span::selection {
background: rgba(#4C7DE1, 0.18);
}
此解決方案有效,但不適用於所有文本。例如,下面的文本包含一個逗號,數字,大寫字母。請注意,選擇在所有單詞中都不一致。

我想說的是,采用多行選擇風格是很棘手的,因此不應在網站上全局使用。如果僅將其用於一個段落,也許完全沒問題。
Demo:https://codepen.io/shadeed/pen/c6d187eadc8251fcce7a8f85506a9ee3?editors=1100
通過 ::selection 和 text-shadow 獲得創意
由於 text-shadow 是自定義選擇受支持的屬性之一,因此我們可以通過使用多個文本陰影來獲得具有一些有趣效果的創意。
長陰影選擇

p::selection {
color: #444444;
background: #ffffff;
text-shadow: 1px 0px 1px #cccccc, 0px 1px 1px #eeeeee, 2px 1px 1px #cccccc, 1px 2px 1px #eeeeee, 3px 2px 1px #cccccc, 2px 3px 1px #eeeeee, 4px 3px 1px #cccccc, 3px 4px 1px #eeeeee, 5px 4px 1px #cccccc, 4px 5px 1px #eeeeee, 6px 5px 1px #cccccc, 5px 6px 1px #eeeeee, 7px 6px 1px #cccccc;
}
輪廓文字選擇

根據本文有關CSS技巧的文章,我們可以使用 text-shadow 模擬文本輪廓。
p::selection {
color: #fff;
text-shadow:
-1px -1px 0 #000,
1px -1px 0 #000,
-1px 1px 0 #000,
1px 1px 0 #000;
}
模糊選擇

另一個有趣的效果是使所選文字模糊。通過使顏色 transparent,文本陰影將仍然存在並且模仿模糊效果。
p::selection {
color: transparent;
text-shadow: 0 0 3px #fff;
}
而且,我敢肯定,你可以拿出越來越多的例子。
文本陰影和性能
建議不要使用沉重的文本陰影樣式,因為它們會導致性能問題。如下示例

霓虹燈效果非常沉重。請注意,在選擇文本時,在我選擇的時間和所選樣式出現的時間之間存在一個延遲。另外,請注意頂部和左側的故障。請小心使用 text-shadow。