計(jì):WXSS 選擇器課程之 ::selection 偽元素實(shí)戰(zhàn))
1. 微信小程序里 ::selection 偽元素到底能改什么先回答一個(gè)最常被問(wèn)到的問(wèn)題微信小程序 WXSS 里的::selection偽元素是用來(lái)控制用戶長(zhǎng)按選中文本時(shí)那塊高亮區(qū)域的樣式的。你在頁(yè)面上按住一段文字拖動(dòng)出現(xiàn)的藍(lán)色或綠色背景就是它在起作用。默認(rèn)情況下小程序在 iOS 和 Android 上給出的選中色并不一致iOS 偏藍(lán)、Android 偏青做界面設(shè)計(jì)時(shí)如果品牌色是橙色或紫色這個(gè)默認(rèn)高亮就會(huì)顯得很跳。它適合誰(shuí)適合正在做小程序界面設(shè)計(jì)、希望把閱讀類(lèi)、筆記類(lèi)、協(xié)議類(lèi)頁(yè)面的細(xì)節(jié)打磨統(tǒng)一的初學(xué)者。你不需要懂復(fù)雜的渲染原理只要會(huì)寫(xiě) WXSS 選擇器就能改。但要注意一個(gè)硬限制::selection能應(yīng)用的屬性非常少只有color、background-color、cursor、outline這幾個(gè)你寫(xiě)font-size、padding、border-radius都是無(wú)效的瀏覽器和小程序渲染層會(huì)直接忽略。我試過(guò)在view和text上分別加::selection結(jié)果差別很大這也是本篇要重點(diǎn)講清楚的地方。很多教程只給一段 CSS 就結(jié)束了但小程序和普通網(wǎng)頁(yè)不一樣它的文本節(jié)點(diǎn)渲染依賴組件類(lèi)型。text組件是專門(mén)承載文本的選中行為正常而view里的純文字在部分基礎(chǔ)庫(kù)版本下選中高亮根本觸發(fā)不了或者只在開(kāi)發(fā)者工具里有效、真機(jī)上失效。所以這篇的路線是先講清楚::selection在小程序里的能力邊界再給你可直接復(fù)制的 WXSS 代碼然后教你怎么在真機(jī)上驗(yàn)證最后把常見(jiàn)的報(bào)錯(cuò)和“寫(xiě)了沒(méi)效果”的坑一個(gè)個(gè)排掉。全程圍繞微信小程序、WXSS、選擇器、::selection、偽元素這幾個(gè)關(guān)鍵詞展開(kāi)你跟著做就能看到效果。需要說(shuō)明的是::selection是偽元素寫(xiě)法上是雙冒號(hào)。老教程里你會(huì)看到單冒號(hào)的:selection那是早期 CSS2 的寫(xiě)法現(xiàn)在標(biāo)準(zhǔn)是雙冒號(hào)小程序里也建議統(tǒng)一用雙冒號(hào)避免解析歧義。另外 Firefox 用的是::-moz-selection但小程序運(yùn)行環(huán)境不是 Firefox所以這個(gè)前綴在小程序里不需要寫(xiě)寫(xiě)了也不生效反而增加維護(hù)成本。還有一個(gè)容易被忽略的點(diǎn)::selection是全局作用域的偽元素你寫(xiě)一個(gè)裸的::selection {}它會(huì)作用于當(dāng)前頁(yè)面所有可選中文本。如果你只想讓某一段文字有特殊高亮就得配合類(lèi)選擇器或后代選擇器比如.article ::selection。這個(gè)組合寫(xiě)法是后面配置章節(jié)的核心先記住這個(gè)結(jié)構(gòu)。2. 接入前的準(zhǔn)備TaoToken 配置與小程序工程結(jié)構(gòu)在正式寫(xiě)::selection之前先把開(kāi)發(fā)環(huán)境和輔助工具理順。如果你只是本地調(diào)樣式其實(shí)不需要任何網(wǎng)絡(luò)服務(wù)微信開(kāi)發(fā)者工具就夠了。但如果你在做 AI 輔助的界面生成、或者想讓模型幫你批量產(chǎn)出 WXSS 選擇器代碼那可以配一個(gè)穩(wěn)定的模型調(diào)用入口。這里我用 TaoToken 來(lái)做演示它的 API 地址是https://taotoken.net/api官網(wǎng)在https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content需要自己拿 Key 的話去控制臺(tái)建一個(gè)就行。先說(shuō)清楚::selection本身是純前端樣式不依賴任何后端。TaoToken 在這里的角色是幫你生成和校對(duì) WXSS 代碼片段比如你描述“我要一個(gè)橙色選中高亮、文字變白的效果”讓模型直接吐可復(fù)制的代碼。所以這一章的重點(diǎn)是工程結(jié)構(gòu) 可選的模型接入兩條線都給你。小程序工程里和樣式相關(guān)的文件主要是這幾個(gè)app.wxss是全局樣式pages/xxx/xxx.wxss是頁(yè)面級(jí)樣式組件還有自己的.wxss。::selection寫(xiě)在哪一層作用范圍就不一樣。寫(xiě)在app.wxss里是全局生效寫(xiě)在頁(yè)面 wxss 里只影響當(dāng)前頁(yè)面。我的建議是全局默認(rèn)色寫(xiě)在app.wxss頁(yè)面特殊高亮寫(xiě)在頁(yè)面 wxss這樣層次清晰。如果你要用模型輔助生成代碼配置方式如下。以常見(jiàn)的 OpenAI 兼容客戶端為例Base URL 填https://taotoken.net/apiAPI Key 填你在控制臺(tái)生成的 KeyModel ID 填你選用的模型標(biāo)識(shí)。這三件套缺一不可很多人只填了 Key 忘了 Base URL結(jié)果請(qǐng)求打到默認(rèn)地址上直接 401。下面是一個(gè)可復(fù)制的配置片段路徑按你實(shí)際使用的工具調(diào)整{ base_url: https://taotoken.net/api, api_key: sk-你的Key, model: 你的模型ID, timeout: 60 }如果你用的是 Claude Code 這類(lèi)編碼工具配置思路一樣Base URL 指向https://taotoken.net/apiKey 和 Model ID 對(duì)應(yīng)填好。需要看詳細(xì)接入步驟的話接入文檔在https://taotoken.net/docAPI Keys 管理在https://taotoken.net/api-keys。這兩個(gè) deep link 都帶了歸因參數(shù)方便你直接跳轉(zhuǎn)。工程結(jié)構(gòu)上我建議你新建一個(gè)測(cè)試頁(yè)面比如pages/selection-demo/selection-demo包含四個(gè)文件.wxml、.wxss、.js、.json。這樣調(diào)試::selection不會(huì)污染你現(xiàn)有的業(yè)務(wù)頁(yè)面。.json里記得寫(xiě){navigationBarTitleText: 選中高亮測(cè)試}方便真機(jī)預(yù)覽時(shí)確認(rèn)頁(yè)面沒(méi)跑錯(cuò)。還有一點(diǎn)真機(jī)預(yù)覽需要你在微信開(kāi)發(fā)者工具里點(diǎn)“預(yù)覽”用手機(jī)微信掃碼?;A(chǔ)庫(kù)版本建議選 2.20.0 以上太老的版本對(duì)偽元素支持不穩(wěn)定。你可以在開(kāi)發(fā)者工具右上角“詳情”→“本地設(shè)置”里調(diào)整調(diào)試基礎(chǔ)庫(kù)版本。這一步做完環(huán)境就齊了下一章直接上代碼。3. 可復(fù)制的 WXSS 配置::selection 完整代碼片段這一章是核心給你能直接粘貼運(yùn)行的代碼。先明確一個(gè)原則::selection只對(duì)text組件和可選中文本穩(wěn)定生效view里的文字要配合user-select相關(guān)行為但小程序?qū)ser-select的支持也有限所以最穩(wěn)的做法是把要選中的文字放進(jìn)text里。先看 WXML 結(jié)構(gòu)我準(zhǔn)備了三種場(chǎng)景全局默認(rèn)、指定類(lèi)名、指定組件內(nèi)view classpage view classtitle默認(rèn)全局選中效果/view text classnormal-text這是一段普通文本長(zhǎng)按可以選中觀察高亮顏色。/text view classtitle指定類(lèi)名的高亮/view text classbrand-text這段文字用了品牌色高亮選中后背景變橙色、文字變白。/text view classtitle組件內(nèi)局部高亮/view view classarticle text文章段落一選中時(shí)走 article 作用域下的樣式。/text text文章段落二同樣受 article 作用域影響。/text /view /view對(duì)應(yīng)的 WXSS 配置如下你可以整段復(fù)制到頁(yè)面 wxss 里/* 全局默認(rèn)所有可選中文本選中后深灰底白字 */ ::selection { color: #ffffff; background-color: #333333; } /* 指定類(lèi)名品牌橙色高亮 */ .brand-text::selection { color: #ffffff; background-color: #ff6a00; } /* 作用域限定只影響 .article 內(nèi)部的文本 */ .article ::selection { color: #1a1a1a; background-color: #ffe08a; } /* 基礎(chǔ)排版方便觀察效果 */ .page { padding: 32rpx; } .title { font-size: 30rpx; color: #888888; margin: 32rpx 0 16rpx; } .normal-text, .brand-text { font-size: 32rpx; line-height: 1.8; display: block; margin-bottom: 16rpx; } .article text { display: block; font-size: 32rpx; line-height: 1.8; margin-bottom: 12rpx; }注意.article ::selection中間有個(gè)空格這表示后代選擇器意思是.article內(nèi)部所有元素的選中樣式。如果你寫(xiě)成.article::selection那就是.article這個(gè)元素自身的選中樣式兩者作用范圍不同別寫(xiě)錯(cuò)。這是選擇器章節(jié)里最容易混的點(diǎn)。再?gòu)?qiáng)調(diào)一次屬性限制上面只用了color和background-color這是安全范圍。你如果加border-radius: 4rpx在小程序里不會(huì)報(bào)錯(cuò)但也不會(huì)有圓角效果因?yàn)檫x中高亮的繪制由渲染層控制不接受圓角。outline和cursor理論上支持但小程序是觸屏環(huán)境cursor基本沒(méi)意義outline在選中態(tài)也不明顯所以實(shí)戰(zhàn)里就聚焦顏色兩個(gè)屬性。如果你想讓全局默認(rèn)和頁(yè)面特殊高亮共存就把全局那段放進(jìn)app.wxss頁(yè)面特殊的那兩段放進(jìn)頁(yè)面 wxss。優(yōu)先級(jí)上頁(yè)面 wxss 的同類(lèi)選擇器會(huì)覆蓋全局所以.brand-text::selection會(huì)蓋過(guò)全局的::selection這正是我們想要的效果。配置完保存開(kāi)發(fā)者工具模擬器里就能直接長(zhǎng)按選中看效果了。4. 真機(jī)驗(yàn)證請(qǐng)求與成功結(jié)果確認(rèn)代碼寫(xiě)完怎么確認(rèn)它真的生效分兩步開(kāi)發(fā)者工具模擬器驗(yàn)證 真機(jī)預(yù)覽驗(yàn)證。模擬器快但模擬器和真機(jī)渲染有差異尤其是選中高亮這種和系統(tǒng)交互相關(guān)的樣式必須真機(jī)過(guò)一遍才算數(shù)。先在開(kāi)發(fā)者工具里操作編譯后用鼠標(biāo)在text文字上按住拖動(dòng)模擬長(zhǎng)按選中。如果看到背景色變成你配置的顏色說(shuō)明選擇器寫(xiě)對(duì)了。如果沒(méi)變化先檢查三點(diǎn)文字是不是放在text里、選擇器有沒(méi)有拼錯(cuò)、基礎(chǔ)庫(kù)版本夠不夠。模擬器里選中高亮有時(shí)顯示不明顯可以放大模擬器比例再看。真機(jī)驗(yàn)證步驟點(diǎn)開(kāi)發(fā)者工具頂部“預(yù)覽”生成二維碼手機(jī)微信掃碼打開(kāi)。在手機(jī)上長(zhǎng)按文字出現(xiàn)選中手柄后拖動(dòng)觀察高亮區(qū)域顏色。這里有個(gè)細(xì)節(jié)iOS 和 Android 的選中手柄樣式不同但背景色應(yīng)該都是你配置的顏色。如果 iOS 生效、Android 不生效大概率是基礎(chǔ)庫(kù)或系統(tǒng) WebView 版本問(wèn)題換個(gè)基礎(chǔ)庫(kù)再試。成功的結(jié)果應(yīng)該長(zhǎng)這樣全局文本選中是深灰底白字.brand-text選中是橙底白字.article內(nèi)部選中是淺黃底深字。三種效果互不干擾說(shuō)明作用域和優(yōu)先級(jí)都正確。你可以把下面這個(gè)驗(yàn)證清單對(duì)著過(guò)一遍驗(yàn)證項(xiàng)預(yù)期結(jié)果不通過(guò)時(shí)先查全局文本選中深灰底白字app.wxss是否引入品牌文本選中橙底白字類(lèi)名是否拼寫(xiě)一致文章區(qū)選中淺黃底深字后代選擇器空格是否漏寫(xiě)真機(jī)與模擬器一致顏色相同基礎(chǔ)庫(kù)版本是否過(guò)低如果你在驗(yàn)證過(guò)程中想讓模型幫你分析“為什么 Android 上沒(méi)生效”可以把現(xiàn)象描述給模型通過(guò)模型對(duì)話入口https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content進(jìn)去問(wèn)把 WXSS 代碼和基礎(chǔ)庫(kù)版本一起貼給它通常能快速定位。但記住樣式問(wèn)題九成出在選擇器寫(xiě)法和組件類(lèi)型上先自己按清單排查一遍。真機(jī)驗(yàn)證還有一個(gè)坑部分安卓機(jī)型在text上長(zhǎng)按會(huì)觸發(fā)系統(tǒng)復(fù)制菜單選中高亮一閃而過(guò)。這時(shí)候你需要在app.json或頁(yè)面配置里確認(rèn)沒(méi)有禁用文本選擇同時(shí)確認(rèn)text沒(méi)有設(shè)置selectablefalse。默認(rèn)text是可選中的但如果你從別處復(fù)制了代碼帶了這個(gè)屬性就會(huì)導(dǎo)致選中行為被關(guān)掉::selection自然無(wú)從觸發(fā)。驗(yàn)證通過(guò)后建議你把三種效果的截圖存下來(lái)作為界面設(shè)計(jì)規(guī)范的一部分。團(tuán)隊(duì)協(xié)作時(shí)選中高亮色應(yīng)該和品牌色體系對(duì)齊不要每個(gè)頁(yè)面各寫(xiě)一套。統(tǒng)一放在app.wxss里維護(hù)頁(yè)面只做必要的覆蓋這樣后期改色只改一處。5. 常見(jiàn)報(bào)錯(cuò)與排查401、local proxy failed、reading choices這一章把你在配置和調(diào)試::selection過(guò)程中可能撞上的報(bào)錯(cuò)集中排一遍。注意::selection本身是純樣式不會(huì)產(chǎn)生網(wǎng)絡(luò)報(bào)錯(cuò)但如果你同時(shí)在做模型輔助生成代碼就會(huì)遇到接口層的錯(cuò)誤。兩類(lèi)問(wèn)題分開(kāi)講。先說(shuō)樣式層“寫(xiě)了沒(méi)效果”的排查。第一種選擇器拼寫(xiě)錯(cuò)誤比如寫(xiě)成::seletion少個(gè) c或者用了單冒號(hào):selection。小程序不會(huì)報(bào)錯(cuò)只是靜默不生效所以一定要對(duì)著代碼逐字檢查。第二種文字放在view里而不是text里view的文本選中行為不穩(wěn)定換成text基本能解決。第三種作用域?qū)戝e(cuò).article::selection和.article ::selection差一個(gè)空格效果完全不同。再說(shuō)接口層報(bào)錯(cuò)這些通常出現(xiàn)在你用模型生成或校對(duì)代碼時(shí)。401一般是沒(méi)有正確攜帶 API Key或者 Key 填錯(cuò)、過(guò)期。檢查你的配置里api_key字段是否完整注意不要有多余空格。local proxy failed通常是本地網(wǎng)絡(luò)配置或客戶端代理設(shè)置問(wèn)題檢查你的工具是否配置了不可用的本地轉(zhuǎn)發(fā)地址把它清掉直連https://taotoken.net/api再試。reading choices這類(lèi)報(bào)錯(cuò)多半是響應(yīng)結(jié)構(gòu)和你客戶端預(yù)期的格式不匹配常見(jiàn)于流式返回被中斷或模型返回了非預(yù)期結(jié)構(gòu)。排查方法是先用一個(gè)最簡(jiǎn)單的請(qǐng)求驗(yàn)證連通性確認(rèn) Base URL、Key、Model ID 三件套都對(duì)再逐步加復(fù)雜度。如果你用的是 Claude Code 或 Cline 這類(lèi)工具配置里 Base URL 一定要寫(xiě)全https://taotoken.net/api不要只寫(xiě)域名。OAuth相關(guān)報(bào)錯(cuò)一般出現(xiàn)在需要授權(quán)登錄的工具里如果你用的是 API Key 模式就不會(huì)碰到 OAuth。確認(rèn)你走的是 Key 認(rèn)證而不是賬號(hào)授權(quán)流程。下面這張對(duì)照表幫你快速定位報(bào)錯(cuò)關(guān)鍵詞常見(jiàn)原因處理方向401Key 缺失或錯(cuò)誤核對(duì) api_key 字段local proxy failed本地轉(zhuǎn)發(fā)配置異常清除代理配置直連reading choices響應(yīng)結(jié)構(gòu)不匹配先用簡(jiǎn)單請(qǐng)求驗(yàn)證OAuth認(rèn)證模式選錯(cuò)改用 API Key 模式樣式層還有一個(gè)隱蔽問(wèn)題你在app.wxss里寫(xiě)了::selection但頁(yè)面 wxss 里又寫(xiě)了一個(gè)不帶作用域的::selection后者會(huì)覆蓋前者導(dǎo)致你以為全局配置失效。排查時(shí)用開(kāi)發(fā)者工具的樣式面板選中文字后看實(shí)際生效的是哪條規(guī)則一目了然。最后提醒::selection不要和user-select: none混用在同一元素上。如果你給某段文字設(shè)了不可選中那它永遠(yuǎn)不會(huì)有選中高亮這不是 bug是預(yù)期行為。做界面設(shè)計(jì)時(shí)可復(fù)制的內(nèi)容才需要配選中高亮純展示的標(biāo)題可以不配。6. 從選中高亮到整體界面規(guī)范下一步怎么走::selection只是 WXSS 選擇器體系里的一個(gè)小點(diǎn)但它能帶出整套界面設(shè)計(jì)思路。你把這一個(gè)偽元素吃透其實(shí)順帶理解了選擇器作用域、優(yōu)先級(jí)、組件差異這三件事這三件事是后面做任何小程序界面都繞不開(kāi)的基礎(chǔ)。下一步建議你做的是把選中高亮納入項(xiàng)目的設(shè)計(jì)變量體系。比如在app.wxss頂部定義一組顏色變量選中色引用變量而不是寫(xiě)死色值page { --selection-bg: #ff6a00; --selection-color: #ffffff; } ::selection { color: var(--selection-color); background-color: var(--selection-bg); }這樣改品牌色時(shí)只動(dòng)變量所有頁(yè)面的選中高亮一起變。小程序?qū)?CSS 變量的支持是穩(wěn)定的放心用。這個(gè)技巧在閱讀類(lèi)、協(xié)議類(lèi)頁(yè)面特別實(shí)用用戶長(zhǎng)按復(fù)制條款時(shí)高亮色和品牌一致體驗(yàn)會(huì)好很多。如果你在做的項(xiàng)目涉及大量文本交互比如筆記、聊天記錄、文檔預(yù)覽那選中高亮的統(tǒng)一只是第一步。接下來(lái)可以研究::selection和user-select的配合控制哪些區(qū)域可選中、哪些不可選中避免用戶誤選到按鈕文字或裝飾性文本。這些都屬于界面細(xì)節(jié)但正是這些細(xì)節(jié)決定了一個(gè)小程序看起來(lái)是“能用”還是“精致”。需要長(zhǎng)期做編碼和 Agent 輔助開(kāi)發(fā)的話可以考慮用 Coding Plan 把模型調(diào)用固定下來(lái)入口在https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content配合 API Keys 頁(yè)面管理你的憑證。這樣你在批量生成 WXSS 選擇器代碼、校對(duì)樣式規(guī)范時(shí)不用每次重新配環(huán)境。回到::selection本身你現(xiàn)在手里應(yīng)該有了可復(fù)制的代碼、真機(jī)驗(yàn)證的方法、以及一份排錯(cuò)清單。最實(shí)用的建議是把這篇里的測(cè)試頁(yè)面保留在你的工程里以后每次調(diào)整全局樣式都到這個(gè)頁(yè)面長(zhǎng)按選中看一眼確認(rèn)高亮色沒(méi)被意外覆蓋。這個(gè)習(xí)慣能幫你省下大量“上線后才發(fā)現(xiàn)顏色不對(duì)”的返工時(shí)間。