從0開(kāi)始編寫一個(gè)開(kāi)關(guān)組件
開(kāi)關(guān)按鈕似乎是開(kāi)發(fā)人員和設(shè)計(jì)師最喜歡的展示他們的動(dòng)畫、設(shè)計(jì)和雙關(guān)語(yǔ)技能的方式。甚至還有一個(gè)專門用于開(kāi)關(guān)按鈕的Codepen集合。
雖然我認(rèn)識(shí)到其中大部分都是有趣的實(shí)驗(yàn),但經(jīng)驗(yàn)告訴我,某些地方的開(kāi)發(fā)人員會(huì)將其中一個(gè)實(shí)驗(yàn)復(fù)制到一個(gè)真正面向用戶的項(xiàng)目中。這些控件多數(shù)情況下是不可訪問(wèn)的,并且在很多情況下會(huì)存在可用性問(wèn)題。
對(duì)于這篇文章,我只提供將一個(gè)標(biāo)準(zhǔn)復(fù)選框可視化轉(zhuǎn)換為一個(gè)可視開(kāi)關(guān)的樣式。沒(méi)有ARIA,沒(méi)有腳本,沒(méi)有特殊特性。一如果CSS文件不加載,按照我“從0開(kāi)始編寫自定義單選按鈕和復(fù)選框”一文中的方法,你也可以得到一個(gè)可以運(yùn)行的持續(xù)增強(qiáng)的復(fù)選框。
如果你想以函數(shù)和樣式來(lái)構(gòu)建一個(gè)原生開(kāi)關(guān),那么你需要看看ARIA開(kāi)關(guān)作用, 你會(huì)立即明白,一個(gè)開(kāi)關(guān)會(huì)影響一個(gè)應(yīng)用程序, 用純文本向用戶去解釋這一點(diǎn), 你會(huì)意識(shí)到, 如果不能正確做到這一點(diǎn),就會(huì)帶來(lái)一個(gè)A級(jí)WCAG違反(Level A WCAG violation)。
例子
這個(gè)codepen會(huì)在你的瀏覽器中顯示一個(gè)默認(rèn)的復(fù)選框,同時(shí)也會(huì)顯示樣式化的復(fù)選框。這個(gè)簡(jiǎn)單的示例沒(méi)有顯示你應(yīng)該支持的所有可能的狀態(tài)和特性。你可能會(huì)立即注意到,它看起來(lái)與人們所期望的iOS開(kāi)關(guān)并不完全一樣,主要是因?yàn)槲覀儗?duì)它應(yīng)用了一些可訪問(wèn)性和可用性的最佳實(shí)踐。我將在下面介紹所有這些,在本文的最后有一個(gè)示例,展示了將所有東西封裝在一組開(kāi)關(guān)中。

如果示例沒(méi)有加載,請(qǐng)直接訪問(wèn)這個(gè)codepen。
基本樣式
如上面提到的,我使用了一些現(xiàn)有的代碼。我隱藏了復(fù)選框,但并沒(méi)有從DOM或可訪問(wèn)樹(shù)中刪除它。我使用::before來(lái)生成膠囊形狀,使用::after來(lái)生成拇指指甲形狀。所有大小調(diào)整都是以em為單位,因此這些大小會(huì)根據(jù)周圍的文本進(jìn)行縮放。灰色(#767676)與白色背景的對(duì)比度為4.5:1,而綠色(#36a829)與白色的對(duì)比度為3:1。這些選擇器看起來(lái)可能有點(diǎn)冗長(zhǎng),但是我避免了使用:not(),因?yàn)镮E無(wú)法處理其中的多個(gè)選擇器,因此我的代碼沒(méi)有減少多少。

獲得焦點(diǎn)和懸停
支持鍵盤用戶以及觸摸和鼠標(biāo)用戶是非常重要的。無(wú)論你開(kāi)發(fā)的懸停樣式是什么,當(dāng)用戶在頁(yè)面上進(jìn)行選項(xiàng)卡切換或焦點(diǎn)以編程方式放置在復(fù)選框上時(shí),懸停樣式都需要是清晰而明顯的。我在這里做了三件事: 我把標(biāo)簽文本變成藍(lán)色,給整個(gè)膠囊形狀添加了陰影,還在拇指指甲形狀上添加了一個(gè)小圓盤。
單獨(dú)使用它們可能太明顯了,但是當(dāng)我將它們組合在一起使用時(shí),我有限的用戶測(cè)試告訴我它們確實(shí)起到了作用并且沒(méi)有影響界面。

禁用的復(fù)選框
有時(shí)一些區(qū)域是要被禁用的,而在原生控件中,這個(gè)操作是通過(guò)將它們?cè)O(shè)置為灰色來(lái)進(jìn)行可視化通信完成的。因?yàn)闆](méi)有對(duì)比要求,我們可以在這里隨意演示一下。我通過(guò)清除背景、亮化邊框和文本來(lái)實(shí)現(xiàn)變灰顯示方法。雖然一個(gè)禁用的控件無(wú)法接收焦點(diǎn),但我們可以懸停在該控件上,以便我們想要撤消這些樣式。

不確定的狀態(tài)
復(fù)選框有第三種狀態(tài)(開(kāi)關(guān)控件沒(méi)有)。此狀態(tài)不是通過(guò)HTML設(shè)置的,而是通過(guò)腳本設(shè)置的。你可以在JavaScript中這樣做 :getElementById(idRef).indeterminate='true';
你能發(fā)現(xiàn)的大多數(shù)示例都沒(méi)有考慮到這一點(diǎn)。與我交互的大多數(shù)開(kāi)發(fā)人員似乎并不知道這一點(diǎn),當(dāng)他們選擇的框架偶爾返回一個(gè)不確定的復(fù)選框時(shí),他們會(huì)感到吃驚(假設(shè)他們只能看到不包含這一點(diǎn)的樣式)。
在本例中,只需將拇指指甲形狀移動(dòng)到中間并選擇一個(gè)中性的背景顏色即可。因?yàn)槲覀円呀?jīng)為禁用的復(fù)選框處理了顏色,所以我們不需要為禁用的不確定情況做任何特殊的事情。

右對(duì)齊
如果我的用戶使用開(kāi)關(guān)控件的經(jīng)驗(yàn)主要來(lái)自iOS,那么你可能希望將開(kāi)關(guān)放在文本的右側(cè),而不是像我這里所做的那樣放在左側(cè)。最主要的是調(diào)整標(biāo)簽文本,以便在右邊留出空間,然后將你的::before和::after放在右邊,適當(dāng)?shù)卦O(shè)置拇指指甲形狀間距。

減少運(yùn)動(dòng)
開(kāi)關(guān)動(dòng)畫對(duì)某些用戶造成問(wèn)題的可能性很低。但是,用戶也有可能會(huì)縮放內(nèi)容,從而使開(kāi)關(guān)填充整個(gè)屏幕,在這種大小下可能會(huì)出現(xiàn)問(wèn)題。我們可以很方便地通過(guò)一個(gè)特性查詢來(lái)禁用該動(dòng)畫。

Windows高對(duì)比度模式
Windows為用戶提供了一種方法,可以剝離web頁(yè)面的所有顏色,并用用戶定義的系統(tǒng)顏色子集替換它們。你不能定義顏色,但是你可以通過(guò)關(guān)鍵字來(lái)指定應(yīng)該在何處應(yīng)用哪種系統(tǒng)顏色。在這里,我們使用了一個(gè)專有的特性查詢,并設(shè)置了所有我們需要用來(lái)表示控件狀態(tài)的顏色。


當(dāng)運(yùn)行在Windows高對(duì)比度模式下,Wifi復(fù)選框獲得焦點(diǎn)時(shí),在Microsoft Edge中所看到的切換開(kāi)關(guān)。
暗黑配色方案
在Safari和Firefox的預(yù)發(fā)布版中,我們都有prefers-color-scheme媒體查詢,它允許用戶選擇查看可能具有黑色主題的頁(yè)面。實(shí)現(xiàn)這一點(diǎn)是一個(gè)選擇好的顏色與良好的對(duì)比度的問(wèn)題。在我的示例中,我將表單重置為接近黑色(#101010),文本重置為白色。綠色仍然有好的對(duì)比度(6.2:1),但是我需要改變獲得焦點(diǎn)/懸停文本的藍(lán)色,我把邊框和背景顏色調(diào)亮一點(diǎn)(#808080),以獲得4.8:1的對(duì)比度。你可以看到針對(duì)禁用狀態(tài)和不確定狀態(tài)的其他一些調(diào)整,以及我在獲得焦點(diǎn)/懸停上使用的SVG。


將Wifi復(fù)選框選中并在暗黑模式下運(yùn)行時(shí),在Firefox67(開(kāi)發(fā)者版本)中所看到的開(kāi)關(guān)。
從右到左
我們不要忘記,有時(shí)我們編寫的內(nèi)容會(huì)自動(dòng)翻譯成其他語(yǔ)言。有時(shí)這些語(yǔ)言不是你現(xiàn)在讀到的西方語(yǔ)言,而是像阿拉伯語(yǔ)或希伯來(lái)語(yǔ)這樣的從右到左(RTL)的語(yǔ)言。如果你正在調(diào)整這段代碼,以便在你自己的庫(kù)中使用,而這個(gè)庫(kù)可能部署在站點(diǎn)之外,那么它最終可能會(huì)變成你沒(méi)有預(yù)料到的一種語(yǔ)言。
雖然我可能不懂波斯語(yǔ)或?yàn)鯛柖颊Z(yǔ),但我可以向周圍的人打聽(tīng)一些了解RTL語(yǔ)言的人,并確認(rèn)一些假設(shè)。大多數(shù)情況下,我們知道不僅文本方向會(huì)改變,開(kāi)關(guān)方向也會(huì)改變。所以我們必須把所有的東西都翻轉(zhuǎn)過(guò)來(lái)才有意義。如果上下文需要一個(gè)交換的開(kāi)關(guān)和文本(例如本地應(yīng)用程序),那么我們也必須翻轉(zhuǎn)它。

總結(jié)
當(dāng)我們將所有這些代碼放在一起時(shí),我們可以擁有一組健壯的開(kāi)關(guān)樣式,這些樣式可以適應(yīng)用戶對(duì)文本大小、對(duì)比度、語(yǔ)言、運(yùn)動(dòng)和交互模式的偏好。隨著越來(lái)越多的特性可用于支持用戶首選項(xiàng)和平臺(tái)特性,我們也可以將它們添加進(jìn)來(lái)。
直接訪問(wèn)這個(gè)codepen。
回顧
本文包含的內(nèi)容:
只使用帶有CSS的復(fù)選框來(lái)增強(qiáng)它們;
支持禁用控件;
支持混合狀態(tài)的復(fù)選框;
按文本樣式縮放,符合WCAG 1.4.12:文本間距(A);
顏色達(dá)到至少3:1對(duì)比度,符合WCAG 1.4.11:非文本對(duì)比度(AA);
支持Windows高對(duì)比度模式;
支持prefers-reduced-motion;
支持prefers-color-scheme;
支持打印(甚至不需要列出來(lái));
避免開(kāi)關(guān)角色;
使用RTL語(yǔ)言運(yùn)行;
在拇指指甲形狀上使用一個(gè)點(diǎn)來(lái)避免只關(guān)注顏色的風(fēng)格,;
在IE11, Edge, Firefox, Chrome, Safari運(yùn)行良好。
我考慮過(guò)把它們做成一個(gè)開(kāi)關(guān)清單,但這似乎沒(méi)有必要。
英文原文:http://adrianroselli.com/2019/03/under-engineered-toggles.html?utm_source=CSS-Weekly&utm_campaign=Issue-359&utm_medium=web?
譯者:浣熊君( ????? )
最后
1.看到這里了就點(diǎn)個(gè)在看支持下吧,你的「在看」是我創(chuàng)作的動(dòng)力。
2.關(guān)注公眾號(hào)程序員成長(zhǎng)指北,「帶你一起學(xué)Node」!
3.我是kaola?,可以添加我的微信【ikoala520】,拉你進(jìn)技術(shù)交流群一起學(xué)習(xí)。
“在看轉(zhuǎn)發(fā)”是最大的支持
