Web用戶體驗設(shè)計提升實踐
時間:2023-10-03 11:12:01 | 來源:網(wǎng)站運(yùn)營
時間:2023-10-03 11:12:01 來源:網(wǎng)站運(yùn)營
Web用戶體驗設(shè)計提升實踐:
本文首發(fā)于微信公眾號“Shopee技術(shù)團(tuán)隊”。前言
本文是基于 Shopee 供應(yīng)鏈團(tuán)隊內(nèi)部 WMS(Warehouse Management System,倉庫管理系統(tǒng)) 項目的整體重構(gòu),總結(jié)而出的一份 Web 用戶體驗設(shè)計提升指南。
因為是對已經(jīng)存在的項目進(jìn)行完全的推翻重構(gòu),所以在整個過程中,我們一直在思考如何盡可能地站在用戶的角度,通過前端設(shè)計去提升改進(jìn)用戶的體驗與感受,真正達(dá)到重構(gòu)的目的及意義。
一個 Web 頁面或是一個 App,想讓別人用得爽,獲得良好的用戶體驗,可能需要包括但不限于:
- 急速的打開速度
- 令人眼前一亮的 UI 設(shè)計
- 酷炫的動畫效果
- 豐富的個性化設(shè)置
- 易用、友好的便捷操作
- 貼心的細(xì)節(jié)
- 關(guān)注殘障人士,良好的可訪問性
- ……
所謂的用戶體驗設(shè)計,是秉承著以用戶為中心的思想的一種設(shè)計手段,以用戶需求為目標(biāo)而進(jìn)行的設(shè)計。設(shè)計過程注重以用戶為中心,用戶體驗的概念從開發(fā)的最早期就開始進(jìn)入整個流程,并貫穿始終。
良好的用戶體驗設(shè)計,是團(tuán)隊在產(chǎn)品開發(fā)中每一個環(huán)節(jié)共同努力的結(jié)果。
本文將主要從
頁面呈現(xiàn)、交互細(xì)節(jié)、可訪問性三個方面入手,分享一些在實際開發(fā)過程中積攢的有益經(jīng)驗。通過這篇文章,你將能:
- 了解到一些細(xì)節(jié)是如何影響用戶體驗的;
- 了解到如何在盡量小的開發(fā)改動下,提升頁面的用戶體驗;
- 了解到一些優(yōu)秀的交互設(shè)計細(xì)節(jié);
- 了解基本的無障礙功能及頁面可訪問性的含義;
- 了解基本的提升頁面可訪問性的方法。
1. 頁面呈現(xiàn)
就整個頁面的展示和頁面內(nèi)容的呈現(xiàn)而言,不同的展示方式,所得到的效果截然不同。
這其中有非常多值得注意的細(xì)節(jié)。接下來分為幾個要點進(jìn)行闡述:
- 自適應(yīng)的布局
- 重點內(nèi)容的排布設(shè)計
- 兼容不同場景與異?;赝?/li>
- 圖片的呈現(xiàn)及異常處理
- 適當(dāng)?shù)倪^渡與動畫
1.1 自適應(yīng)的布局
先來看一些布局相關(guān)的問題。
布局,是前端在重構(gòu)頁面過程中需要提前進(jìn)行規(guī)劃思考的,一般應(yīng)該考慮清楚以下幾個問題:
- 對于 PC 端,項目是全屏布局還是定寬布局?用戶是否還在使用 IE?
- 對于全屏布局,需要適配的最小寬度是多少?
- 對于移動端布局,你知道用戶設(shè)備的分布嗎?最少兼容到 Android 什么版本?iOS 什么版本?
- 內(nèi)容應(yīng)該以什么樣的方式呈現(xiàn)?
到今天,各種設(shè)備浩如煙海,移動端屏幕尺寸紛繁復(fù)雜(下圖僅僅是到 2019 年各種安卓設(shè)備屏幕尺寸圖的分布):
不過,我們的重構(gòu)項目整體是以 PC 為主的 ToB 項目,所以這里主要以 PC 端為例進(jìn)行講解。
對于大部分 PC 端的項目,首先需要考慮的肯定是最外面的一層包裹。假設(shè)就是
.g-app-wrapper
。
<div class="g-app-wrapper"> <!-- 內(nèi)部內(nèi)容 --></div>
首先,對于
.g-app-wrapper
,有幾點是我們在項目開發(fā)前必須弄清楚的:
- 項目是全屏布局還是定寬布局?
- 對于全屏布局,需要適配的最小的寬度是多少?
對于定寬布局,就比較方便了,假設(shè)定寬為
1200px
,那么:
.g-app-wrapper { width: 1200px; margin: 0 auto;}
利用
margin: 0 auto
實現(xiàn)布局的水平居中。在屏幕寬度大于
1200px
時,兩側(cè)留白;屏幕寬度小于
1200px
時,則出現(xiàn)滾動條,保證內(nèi)部內(nèi)容不亂。
現(xiàn)代布局更多的是全屏布局。其實現(xiàn)在也更提倡這種布局,即可隨用戶設(shè)備的尺寸和能力而變化的自適應(yīng)布局。
自適應(yīng)布局通常有左右兩欄,左側(cè)定寬,右側(cè)自適應(yīng)剩余寬度。另外還會有一個最小寬度。那么,它的布局應(yīng)該是這樣:
<div class="g-app-wrapper"> <div class="g-sidebar"></div> <div class="g-main"></div></div>
.g-app-wrapper { display: flex; min-width: 1200px;}.g-sidebar { flex-basis: 250px; margin-right: 10px;}.g-main { flex-grow: 1;}
這里利用了 flex 布局下的
flex-grow: 1
,讓
.main
進(jìn)行伸縮,占滿剩余空間,利用 min-width 保證了整個容器的最小寬度。
這是最基本的自適應(yīng)布局。對于現(xiàn)代布局,我們應(yīng)該盡可能考慮到更多的場景。做到:
底部 footer
下面一種情形也非常常見:
頁面存在一個 footer(頁腳)部分,如果整個頁面的內(nèi)容高度小于視窗的高度,則 footer 固定在視窗底部,如果整個頁面的內(nèi)容高度大于視窗的高度,則 footer 正常流排布(也就是需要滾動到底部才能看到 footer)。
看看效果:
這個需求如果能夠使用 flex 的話,用
justify-content: space-between
可以很好地解決。同理,使用
margin-top: auto
也非常容易完成:
<div class="g-container"> <div class="g-real-box"> ... </div> <div class="g-footer"></div></div>
.g-container { height: 100vh; display: flex; flex-direction: column;}.g-footer { margin-top: auto; flex-shrink: 0; height: 30px; background: deeppink;}
Codepen Demo - sticky footer by flex margin auto
當(dāng)然,實現(xiàn)它的方法有很多,這里僅給出一種推薦的解法。
1.2 重點內(nèi)容的排布設(shè)計
下面這一塊關(guān)于重點內(nèi)容的展示。
1.2.1 重要內(nèi)容及功能的展示
讓吸引用戶注意力的元素前置。如果我們的頁面存在需要讓用戶了解、處理的核心信息或者表單,盡可能將其位置放在上方,讓用戶更容易獲取這部分信息。
將用戶需要的信息、重要的功能展示出來而不是藏起來。
類似于導(dǎo)航、搜索等高頻操作,一定不要讓用戶多次點擊才能用到。
1.2.2 處理動態(tài)內(nèi)容:文本超長
對于所有接收后端接口字段的文本展示類的界面,都需要考慮全面。正常情況如下,是沒有問題的:
但是我們是否考慮到了文本會超長?超長了會折行還是換行?
對于單行文本,使用單行省略:
{ width: 200px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;}
當(dāng)然,目前對于多行文本的超長省略,兼容性也已經(jīng)非常好了:
{ width: 200px; overflow : hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;}
1.2.3 處理動態(tài)內(nèi)容:保護(hù)邊界
對于一些動態(tài)內(nèi)容,我們經(jīng)常使用
min/max-width
或
min/max-height
對容器的高寬限度進(jìn)行合理的控制。
在使用它們的時候,也有一些細(xì)節(jié)需要考慮到。 譬如經(jīng)常會使用
min-width
控制按鈕的最小寬度:
.btn { ... min-width: 120px;}
當(dāng)內(nèi)容比較少的時候是沒問題的,但是如果內(nèi)容比較長,就容易出現(xiàn)問題。下圖就是使用了
min-width
卻沒考慮到按鈕的過長的情況:
這里就需要配合 padding 一起:
.btn { ... min-width: 88px; padding: 0 16px}
借用
Min and Max Width/Height in CSS 中一張非常好的圖,作為釋義:
1.3 兼容不同場景與異?;赝耍嚎諗?shù)據(jù)內(nèi)容展示
這個模塊是兼容不同場景與異常回退,是一個常常被忽略的地方。
頁面經(jīng)常會有列表搜索、列表展示。那么,既然存在數(shù)據(jù)的正常情況,當(dāng)然也會存在搜索不到結(jié)果或者列表無內(nèi)容可展示的情形。
對于這種情況,一定要注意空數(shù)據(jù)結(jié)果頁面的設(shè)計;同時要知道,這也是引導(dǎo)用戶的好地方。對于空數(shù)據(jù)結(jié)果頁面,分清楚:
(1)數(shù)據(jù)為空- 用戶無權(quán)限——要告知用戶無權(quán)限訪問的原因和解決方案
- 搜索無結(jié)果——告知用戶搜索無數(shù)據(jù)的結(jié)果,如有必要可推薦相關(guān)內(nèi)容
- 篩選無結(jié)果——一般直接告知篩選無結(jié)果
- 頁面無數(shù)據(jù)——文案設(shè)計有幾個方向:
- 告訴用戶這里將會存放什么數(shù)據(jù)
- 給用戶一個主動創(chuàng)造數(shù)據(jù)的理由,比如通過話術(shù)引起用戶心理共鳴
- 若頁面無數(shù)據(jù)會給用戶造成困惑,則可以說明原因打消用戶的困惑
(2)異常狀態(tài)- 網(wǎng)絡(luò)異常——指出當(dāng)前狀態(tài)為網(wǎng)絡(luò)異常,并給出解決方案
- 服務(wù)器異常——指出當(dāng)前狀態(tài)為服務(wù)器異常,并給出解決方案
- 加載失敗——加載失敗主要會由網(wǎng)絡(luò)異?;蚍?wù)器異常造成
- 不同的情況可能對應(yīng)不同的空數(shù)據(jù)結(jié)果頁面,附帶不同的操作引導(dǎo)
例如網(wǎng)絡(luò)異常,可以引導(dǎo)用戶刷新頁面:
或者確實是零結(jié)果,譬如沒有訂單信息,可以引導(dǎo)用戶去進(jìn)行訂單的創(chuàng)建(引導(dǎo)消費(fèi)):
小小總結(jié)一下,上述篇幅一直都在闡述一個道理:
開發(fā)時,不能僅僅關(guān)注正?,F(xiàn)象,要多考慮各種異常情況,思考全面,做好各種可能情況的處理。
1.4 圖片的呈現(xiàn)及異常處理
圖片在我們的業(yè)務(wù)中非常常見。但是要完美處理圖片,并不輕松。
1.4.1 給圖片同時設(shè)置高寬
有的時候產(chǎn)品和設(shè)計會商定,只能使用固定尺寸大小的圖片,我們的布局可能是這樣:
對應(yīng)的布局:
<ul class="g-container"> <li> <img src="http://placehold.it/150x100"> <p>圖片描述</p> </li></ul>
ul li img { width: 150px;}
假設(shè)后端接口出現(xiàn)一張非正常大小的圖片,上述不加保護(hù)的布局就會出問題:
所以對于圖片,我們總是建議同時寫上高和寬,避免因為圖片尺寸錯誤帶來的布局問題。
ul li img { width: 150px; height: 100px;}
另外,給
<img>
標(biāo)簽同時寫上高寬,可以在圖片加載之前提前占住位置,避免圖片從未加載狀態(tài)到渲染完成狀態(tài)高寬變化引起的重排問題。
1.4.2 object-fit
限制高寬也可能會出現(xiàn)問題,比如圖片被拉伸了,非常難看:
這個時候我們可以借助
object-fit
,它能夠指定可替換元素的內(nèi)容(也就是圖片)該如何適應(yīng)它的父容器的高寬。
ul li img { width: 150px; height: 100px; object-fit: cover;}
利用
object-fit: cover
,使圖片內(nèi)容在保持寬高比的同時填充元素的整個內(nèi)容框。
object-fit
還有一個配套屬性
object-position
,它可以控制圖片在其內(nèi)容框中的位置(類似于
background-position
),m 默認(rèn)是
object-position: 50% 50%
。如果你不希望圖片居中展示,可以使用它去改變圖片實際展示的位置。
ul li img { width: 150px; height: 100px; object-fit: cover; object-position: 50% 100%;}
像是這樣,
object-position: 100% 50%
指明從底部開始展示圖片。
這里有一個很好的 Demo 可以幫助你理解 object-position
:
CodePen Demo - Object position
1.4.3 考慮屏幕 dpr:響應(yīng)式圖片
正常情況下,圖片的展示應(yīng)該沒有什么問題了,但我們還可以做得更好。
在移動端或者一些高清的 PC 屏幕(例如蘋果的 Mac Book),屏幕的 dpr 可能大于 1。這種時候,我們可能還需要考慮利用多倍圖去適配不同 dpr 的屏幕。
正好,
<img>
標(biāo)簽提供了相應(yīng)的屬性
srcset
供我們操作。
<img src='photo@1x.png' srcset='photo@1x.png 1x, photo@2x.png 2x, photo@3x.png 3x' />
不過,這是比較舊的寫法,
srcset
增加了新的
w
寬度描述符,需要配合
sizes
一起使用,所以更好的寫法是:
<img src = "photo.png" sizes = “(min-width: 600px) 600px, 300px" srcset = “photo@1x.png 300w, photo@2x.png 600w, photo@3x.png 1200w,>
利用
srcset
,我們可以給不同 dpr 的屏幕提供最適合的圖片。
1.4.4 圖片丟失
好了,當(dāng)圖片鏈接沒問題時,已經(jīng)處理好了。接下來還需要考慮,當(dāng)圖片鏈接掛了,應(yīng)該如何處理。
處理的方式有很多種。最好的處理方式,是我在張鑫旭老師《
圖片加載失敗后 CSS 樣式處理最佳實踐》這篇文章中看到的。這里簡單講講:
- 利用圖片加載失敗,觸發(fā)
<img>
元素的 onerror
事件,給加載失敗的 <img>
元素新增一個樣式類; - 利用新增的樣式類,配合
<img>
元素的偽元素,展示默認(rèn)兜底圖的同時,還能一起展示 <img>
元素的 alt
信息。
<img src="test.png" alt="圖片描述" onerror="this.classList.add('error');">
img.error { position: relative; display: inline-block;}img.error::before { content: ""; /** 定位代碼 **/ background: url(error-default.png);} img.error::after { content: attr(alt); /** 定位代碼 **/}
我們利用偽元素
before
,加載默認(rèn)錯誤兜底圖,利用偽元素
after
,展示圖片的
alt
信息:
到此,完整的對圖片的處理就算完成了,完整的 Demo 你可以戳這里看看:
CodePen Demo - 圖片處理。
1.5 適當(dāng)?shù)倪^渡與動畫
好的頁面呈現(xiàn)需要適當(dāng)?shù)倪^渡與動畫,讓整體交互體驗更加流暢。適當(dāng)增加過渡與動畫,能夠很好地讓用戶感知到頁面的變化,它們有如下作用:
- 減少認(rèn)知負(fù)荷
- 防止變化視盲
- 空間上營造更好的印象
- 讓用戶界面鮮活起來
這一塊內(nèi)容也可以放在交互設(shè)計優(yōu)化,讀者朋友們了解就好。
1.5.1 loading 等待動畫
頁面上隨處可見的 loading 效果,其實就是這樣一種作用,讓用戶感知頁面正在加載,或者正在處理某些事務(wù)。
1.5.2 骨架屏動畫
骨架屏的布局與頁面的視覺呈現(xiàn)保持一致,能引導(dǎo)用戶將關(guān)注點聚焦到感興趣的位置,并且能避免過長時間的等待。
1.5.3 滾動平滑:使用 scroll-behavior: smooth
讓滾動絲滑
使用
scroll-behavior: smooth
,可以讓滾動框?qū)崿F(xiàn)平穩(wěn)地滾動,而不是突兀地跳動??纯葱Ч?,假設(shè)如下結(jié)構(gòu):
<div class="g-container"> <nav> <a href="#1">1</a> <a href="#2">2</a> <a href="#3">3</a> </nav> <div class="scrolling-box"> <section id="1">First section</section> <section id="2">Second section</section> <section id="3">Third section</section> </div></div>
不使用
scroll-behavior: smooth
,就是突兀地跳動切換:
要改善這種現(xiàn)象,可以給可滾動容器添加
scroll-behavior: smooth
,實現(xiàn)平滑滾動:
{ scroll-behavior: smooth;}
1.5.4 粘性滾動:使用 scroll-snap-type
優(yōu)化滾動效果
sroll-snap-type
可能算得上是新的滾動規(guī)范里面最核心的一個屬性樣式。
scroll-snap-type:屬性定義在滾動容器中的一個臨時點(snap point)如何被嚴(yán)格地執(zhí)行。
光看定義有點難理解,簡單而言,這個屬性規(guī)定了一個容器是否對內(nèi)部滾動動作進(jìn)行捕捉,并且規(guī)定了如何去處理滾動結(jié)束狀態(tài)。讓滾動操作結(jié)束后,元素停止在適合的位置。
看個簡單示例:
當(dāng)然,
scroll-snap-type
用法非常多,可控制優(yōu)化的點很多,限于篇幅無法一一展開。
1.5.5 控制滾動層級,避免頁面大量重排
這個優(yōu)化可能稍微有一點難理解。需要了解 CSS 渲染優(yōu)化的相關(guān)知識。
先說結(jié)論,控制滾動層級的意思是
盡量讓需要進(jìn)行 CSS 動畫(可以是元素的動畫,也可以是容器的滾動)的元素的 z-index 保持在頁面最上方,避免瀏覽器創(chuàng)建不必要的圖形層(GraphicsLayer),能夠很好地提升渲染性能。
這一點怎么理解呢?一個元素觸發(fā)創(chuàng)建一個 Graphics Layer 層的其中一個因素是:
- 元素有一個 z-index 較低且包含一個復(fù)合層的兄弟元素。
根據(jù)上述這點,我們對滾動性能進(jìn)行優(yōu)化的時候,需要注意兩點:
- 通過生成獨(dú)立的 GraphicsLayer,利用 GPU 加速,提升滾動的性能;
- 如果本身滾動沒有性能問題,不需要獨(dú)立的 GraphicsLayer,也要注意滾動容器的層級,避免因為層級過高而被其他創(chuàng)建了 GraphicsLayer 的元素合并,被動地生成一個 GraphicsLayer ,影響頁面整體的渲染性能。
1.5.6 轉(zhuǎn)場動畫
從一個模塊跳轉(zhuǎn)到另外一個模塊的時候,轉(zhuǎn)場動畫就派上了用場。它的作用在于:在合適的時機(jī),將視線引導(dǎo)到適當(dāng)?shù)奈恢谩?br>
看下面的例子:
在點擊按鈕彈出彈窗的過程中,彈窗不是突兀地出現(xiàn),而是從點擊的地方放大至視窗中間,這個引導(dǎo)的過程讓體驗更加絲滑。
1.5.7 操作動畫
這個和 loading 有點類似,遇到一些耗時操作,比如下載時,我們可以通過定制一個特殊的動畫,減緩用戶等待的煩躁、焦慮感。
上述動畫的代碼,你可以猛擊:
CodePen Demo - Download interaction By Milan Raring
當(dāng)然,除了下載等待,我們也可以在一些重要的操作交互上,例如點贊、關(guān)注等,定制特殊的動畫,讓過程更加生動有趣。下面這個是某網(wǎng)站的點贊動畫:
上述點贊動畫的代碼,你可以猛擊:
CodePen Demo - Twitter 點贊動畫
1.5.8 使用過渡與動畫的誤區(qū)
合理使用動畫能讓頁面增色不少,但同時要避免踩入下面的一些坑:
- 動畫沒有關(guān)聯(lián)性
- 為了動畫而動畫,沒有目的性
- 過于緩慢,阻礙交互
- 不夠明確
簡單解釋一下。譬如動畫關(guān)聯(lián)性,關(guān)聯(lián)性背后的邏輯能幫助用戶在界面布局中理解剛發(fā)生的變化,是什么導(dǎo)致了變化。
下圖中,左邊是關(guān)聯(lián)性差的,右邊是關(guān)聯(lián)性好的:
還有一點,大部分動畫不宜過久,要足夠迅速。
緩慢的動畫產(chǎn)生了不必要的停頓。過渡動畫應(yīng)該保持簡短,因為用戶會頻繁看到它們。讓動畫持續(xù)時間保持在 300ms 或更短。
看下圖演示,同一個轉(zhuǎn)場動畫會被頻繁觸發(fā),所以盡可能地讓每次的動畫不要持續(xù)過久,能夠幫助用戶節(jié)省更多時間。
總而言之,
動畫和過渡要用得恰當(dāng)好處,避免為了動畫而動畫非常重要。
2. 交互設(shè)計優(yōu)化
接下來一個大環(huán)節(jié)是一些關(guān)于交互的細(xì)節(jié)。
什么是交互設(shè)計?交互設(shè)計(Interaction Design, IXD)是定義、設(shè)計人造系統(tǒng)的行為的設(shè)計領(lǐng)域,它定義了
兩個或多個互動的個體之間交流的內(nèi)容和結(jié)構(gòu),使之
互相配合,共同達(dá)成某種目的。
2.1 Web 端交互方式
Web 端交互圍繞計算機(jī)為中心,主要涉及鍵盤、鼠標(biāo)兩類設(shè)備的交互。
關(guān)于交互設(shè)計,一些比較通用的準(zhǔn)則有:
- Don’t make me think
- 符合用戶的習(xí)慣與預(yù)期
- 操作便利
- 做適當(dāng)?shù)奶嵝?/li>
- 不強(qiáng)迫用戶
2.2 Don’t make me think
有一本書就叫
Don’t make me think,它所想表述的核心是,盡可能讓產(chǎn)品做到高可用性,讓用戶無須思考也能明確無誤地使用產(chǎn)品中的各項功能。
那么,我們的頁面如何盡可能做到高可用性呢?
2.2.1 使用習(xí)慣用法
使用習(xí)慣用法。當(dāng)我們設(shè)計一個新的頁面時,頁面位置、功能設(shè)置、視覺元素應(yīng)當(dāng)和慣常用法相差無幾,這樣才能讓用戶有舒適感。
這里并不是要扼殺大家的想象力,讓所有頁面都一成不變。根據(jù)產(chǎn)品的形態(tài)及受眾,大部分頁面是不適用于各種天馬行空的想象的。
例如下面這樣一個 PC 端頁面結(jié)構(gòu),這種布局已經(jīng)非常常見。遇到這種頁面,用戶能夠非??焖俚卦谥付▍^(qū)域找到想要的元素及信息:
可以再和我們的 WMS 重構(gòu)后的頁面作比較,整體是非常類似的:
采用習(xí)慣用法的設(shè)置能夠讓人快速上手新的陌生的頁面或者功能。
2.2.2 降低視覺噪聲
另外一種做法是降低視覺噪聲,讓用戶快速聚焦。
譬如彈窗背后的陰影、虛化,就是非常好的降低視覺噪聲的手段。
這一點還是非常好理解的,也屬于常見設(shè)計手段之一,在我們內(nèi)部的相關(guān)組件、自研組件庫已經(jīng)沉淀得很好了。
2.3 符合用戶的習(xí)慣與預(yù)期
接下來是
符合用戶的習(xí)慣與預(yù)期,它的意義在于減少用戶的思考,符合用戶的習(xí)慣,讓用戶的體驗更加舒適。
下面這幾種彈窗,哪一個是更好的選擇?
三個彈窗可供操作的按鈕分別是:
- 右下角的取消和確認(rèn),同時右上角的 X 可以關(guān)閉彈窗;
- 只有右下角的取消和確認(rèn);
- 只有確認(rèn)按鈕。
更好的選擇應(yīng)該是第一個:同時有取消和確認(rèn)按鈕,右上角的 X 可以關(guān)閉彈窗。因為這樣最符合用戶的習(xí)慣預(yù)期。
看看這個 Windows 下的彈窗:
大部分 Windows 的彈窗,都是有取消、確認(rèn)加上右上角的 X 按鈕的。這種彈窗的好處在于:
- 視覺原因,元素平衡;
- 符合用戶習(xí)慣,大多數(shù)用戶都是 Windows 操作系統(tǒng)過來的;
- 交互一致性,降低用戶學(xué)習(xí)成本;
- 提升頁面的可訪問性和無障礙訪問性。
2.3.1 優(yōu)化手勢:不同場景應(yīng)用不同 cursor
對于不同的內(nèi)容,最好給與不同的
cursor
樣式,CSS 原生提供了非常多種常用的手勢。
在不同的場景使用不同的鼠標(biāo)手勢,
符合用戶的習(xí)慣與預(yù)期,可以很好地提升用戶的交互體驗。
首先對于按鈕,就至少會有三種不同的
cursor
,分別是可點擊、不可點擊、等待中:
{ cursor: pointer; // 可點擊 cursor: not-allowed; // 不可點擊 cursor: wait; // loading}
除此之外,還有一些常見用法:對于一些可輸入的 Input 框,使用
cursor: text
;對于提示 Tips 類,使用
cursor: help
;放大縮小圖片
zoom-in
、
zoom-out
等等:
一些常用的簡單列一列:
- 按鈕可點擊:
cursor: pointer
- 按鈕禁止點擊:
cursor: not-allowed
- 等待 Loading 狀態(tài):
cursor: wait
- 輸入框:
cursor: text
- 圖片查看器可放大可縮?。?code>cursor: zoom-in/ zoom-out
- 提示:
cursor: help
當(dāng)然,實際
cursor
還支持非常多種,可以在
MDN 或者下面這個 CodePen Demo 中查看完整列表:
CodePen Demo - Cursor Demo。
2.3.2 點擊區(qū)域優(yōu)化:偽元素擴(kuò)大點擊區(qū)域
按鈕是我們網(wǎng)頁設(shè)計中十分重要的一環(huán),而按鈕的設(shè)計也與用戶體驗息息相關(guān)。
考慮這樣一個場景:在搖晃的車廂上或者是單手操作著屏幕,有的時候一個按鈕死活也點不到。
讓用戶更容易點擊到按鈕無疑能很好地提升用戶體驗,并提升頁面的訪問性。尤其是在移動端,按鈕通常都很小,但是受限于設(shè)計稿或者整體 UI 風(fēng)格,我們不能直接去改變按鈕元素的高寬。
那么,有什么辦法在不改變按鈕原本大小的情況下增加點擊熱區(qū)呢?
借助偽元素可以輕松實現(xiàn)。偽元素也是可以代表其宿主元素來響應(yīng)鼠標(biāo)交互事件的。我們可以這樣寫:
.btn::before{ content:""; position:absolute; top:-10px; right:-10px; bottom:-10px; left:-10px;}
當(dāng)然,在 PC 端下這樣子看起來有點奇怪,但是合理地用在點擊區(qū)域較小的移動端則能取得十分好的效果:
2.4 操作便利
好的系統(tǒng),操作起來應(yīng)該是流暢的。同時,它能夠通過一些小細(xì)節(jié)打動用戶。
2.4.1 快速選擇優(yōu)化:user-select: all
操作系統(tǒng)或者瀏覽器通常會提供一些快速選取文本的功能??纯聪旅娴氖疽鈭D:
快速單擊兩次,可以選中單個單詞;快速單擊三次,可以選中一整行內(nèi)容。但如果核心內(nèi)容被分隔符分割,或者成為潛藏在一整行中的一部分,這個時候選取起來就比較麻煩。
利用
user-select: all
,可以將需要一次選中的內(nèi)容進(jìn)行包裹,用戶只需要點擊一次,就可以選中該段信息:
.g-select-all { user-select: all}
給需要一次選中的信息加上這個樣式,該細(xì)節(jié)作用在一些需要復(fù)制粘貼的場景時,非常好用。
在我們 WMS 的很多操作頁面,需要頻繁從表格中復(fù)制一些基礎(chǔ)信息,例如下述的
Location ID
、
Cell Name
,由于完整的字段使用了分隔符
-
,所以一次點擊是無法選中整段信息的,而利用
user-select: all
可以很好地解決這個痛點:
別看只是減少一次點擊鼠標(biāo)的次數(shù),但正是這些細(xì)節(jié)的累積,才更能讓用戶感受到開發(fā)者的用心。
CodePen - user-select: all 示例2.4.2 選中樣式優(yōu)化:::selection
CSS 還提供了一個
::selection
偽類,可以控制選中的文本樣式(只能控制
color
、
background
、
text-shadow
),進(jìn)一步加深效果。
CodePen - user-select: all && ::selection 控制選中樣式2.4.3 添加禁止選擇:user-select: none
有快速選擇,也就會有它的對立面——禁止選擇。
對于一些可能頻繁操作的按鈕,可能會出現(xiàn)如下尷尬場景:
- 文本按鈕的快速點擊,觸發(fā)了瀏覽器的雙擊快速選擇,導(dǎo)致文本被選中:
- 翻頁按鈕的快速點擊,觸發(fā)了瀏覽器的雙擊快速選擇:
對于這種場景,我們需要把不可被選中的元素設(shè)置為不可被選中,利用 CSS 可以快速實現(xiàn)這一點:
{ -webkit-user-select: none; /* Safari */ -ms-user-select: none; /* IE 10 and IE 11 */ user-select: none; /* Standard syntax */}
這樣,無論點擊頻率多快,都不會出現(xiàn)內(nèi)容被選中的尷尬情況:
2.5 跳轉(zhuǎn)優(yōu)化
現(xiàn)階段,單頁應(yīng)用(Single Page Application)的應(yīng)用非常廣泛,Vue 、React 等框架大行其道。但是有的常見寫法也容易衍生一些小問題。
譬如,點擊按鈕、文本進(jìn)行路由跳轉(zhuǎn),經(jīng)常會出現(xiàn)這種代碼:
<template> ... <button @click="gotoDetail"> Detail </button> ...<template>...gotoDetail() { this.$router.push({ name: 'xxxxx', });}
大致邏輯就是給按鈕添加一個事件,點擊之后跳轉(zhuǎn)到另外一個路由。當(dāng)然,這個功能本身是沒有問題的,但是沒有考慮到用戶實際使用的場景。
實際使用的時候,用戶可能會希望保留當(dāng)前頁面的內(nèi)容,同時打開一個新的窗口。這個時候,他會嘗試點擊鼠標(biāo)右鍵,選擇
在新標(biāo)簽頁中打開頁面。遺憾的是,上述寫法不支持鼠標(biāo)右鍵打開新頁面。
原因在于瀏覽器是通過讀取
<a>
標(biāo)簽的
href
屬性,來展示類似
在新標(biāo)簽頁中打開頁面這種選項,對于上述寫法,瀏覽器無法識別它是一個可以跳轉(zhuǎn)的鏈接。簡單的示意圖如下:
所以,對于所有路由跳轉(zhuǎn)按鈕,建議都使用
<a>
標(biāo)簽,并且內(nèi)置
href
屬性,填寫跳轉(zhuǎn)的路由地址。實際渲染出來的 DOM 可能類似這樣:
<a href="/xx/detail">Detail</a>
在實際的 WMS 重構(gòu)過程中,我們對于所有有頁面跳轉(zhuǎn)功能的按鈕,包括但不限于路由菜單、面包屑導(dǎo)航、跳轉(zhuǎn)按鈕等,都進(jìn)行了跳轉(zhuǎn)優(yōu)化,以滿足用戶的不同訴求。
路由菜單導(dǎo)航:
表格中的一些按鈕跳轉(zhuǎn):
2.6 表單交互優(yōu)化
輸入及選擇于用戶而言,是一項高交互成本的操作。下面提供了一些小的建議來減少用戶輸入出錯、提升用戶體驗。
2.6.1 盡可能地簡化表單
將表單做得簡單點,確保用戶在抓狂之前能進(jìn)入下一步(表單越復(fù)雜,流失率越高):
對于沒法省去的輸入項,盡可能簡化用戶的輸入:
- 智能預(yù)設(shè)默認(rèn)項
- 輸入時提供智能聯(lián)想
- 對于選擇框,盡可能精簡選項信息
- 使用單選項來代替下拉菜單
2.6.2 及時校驗
表單及時校驗,而不是用戶填完一堆信息,統(tǒng)一提交后才告訴用戶填錯了:
2.6.3 貼心細(xì)節(jié)提示,校驗更寬容
還有一些比較有益的建議,可以有效的提升交互過程中用戶的體驗,根據(jù)實際情況可以考慮:
- 在表單中增加一些提示信息,減少錯誤的幾率
- 嘗試將表單輸入變得更加寬容,讓用戶的填寫更加簡單
2.7 先探索,后表態(tài)
這一點非常有意思,什么叫先探索后表態(tài)呢?就是我們不要一上來就強(qiáng)迫用戶去做一些事情,例如登錄。 想一想一些常用網(wǎng)站的例子:
- 類似虎牙、bilibili 等視頻網(wǎng)站,可以先藍(lán)光體驗,一定觀看時間后才會要求登錄;
- 電商網(wǎng)站,只有到付款的時候,才需要登錄。
上述易用性和先探索后表態(tài)的內(nèi)容,部分來源于 “Learn From What Leading Companies A/B Test”,推薦閱讀。
2.8 結(jié)合產(chǎn)品的創(chuàng)意交互動畫
由于業(yè)務(wù)的類型限制,在這一塊,我們實際中運(yùn)用的并不多,但是它也是增強(qiáng)用戶體驗非常有益且重要的一環(huán),下文將簡單講一講。
這一類交互為結(jié)合產(chǎn)品的創(chuàng)意交互動畫。通過定制化的有儀式感的交互,提升品牌價值,能給予用戶深刻的印象。
結(jié)合產(chǎn)品及業(yè)務(wù)的創(chuàng)意動畫,是需要挖掘,不斷打磨、不斷迭代的。比如 bilibili 官網(wǎng)的頂部 banner,配合一些節(jié)日、活動,經(jīng)常會出現(xiàn)一些有意思的創(chuàng)意交互動畫:
以及這個:
我非常多次在不同地方看到有人討論 bilibili 的頂部 banner 動畫,可見它這塊的動畫是成功的。很好地結(jié)合了一些節(jié)日、實事、熱點,作為一種比較固定的產(chǎn)品去不斷推陳出新,在不同時候帶給用戶不同的體驗。
2.9 字體優(yōu)化
字體的選擇與使用其實是非常有講究的。
在 WMS 項目重構(gòu)過程中,我們使用的全局字體定義是:
font-family: Roboto,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Oxygen,Ubuntu,Fira Sans,Droid Sans,Helvetica Neue,"sans-serif";
。
這里,我們的設(shè)計師對英文字體有一些強(qiáng)限制,首選字體是 Roboto,并且在系統(tǒng)中提供了該字體包。
如果網(wǎng)站沒有強(qiáng)制必須使用某些字體。最新的規(guī)范建議我們使用系統(tǒng)默認(rèn)字體。也就是 “
CSS Fonts Module Level 4: Generic font families” 中新增的
font-family: system-ui
關(guān)鍵字。它能夠自動選擇本操作系統(tǒng)下的默認(rèn)系統(tǒng)字體。
默認(rèn)使用特定操作系統(tǒng)的系統(tǒng)字體可以提高性能,因為瀏覽器或者 WebView 不必去下載任何字體文件,而是使用已有的字體文件。
font-family: system-ui
字體設(shè)置的優(yōu)勢之處在于它與當(dāng)前操作系統(tǒng)使用的字體相匹配,對于文本內(nèi)容而言,它可以得到最恰當(dāng)?shù)恼故尽?br>
舉兩個例子,天貓的字體定義與 Github 的字體定義:
- 天貓:
font-family: "PingFang SC",miui,system-ui,-apple-system,BlinkMacSystemFont,Helvetica Neue,Helvetica,sans-serif;
- Github:
font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;
簡單而言,它們總體遵循了以下幾項基本原則:
2.9.1 盡量使用系統(tǒng)默認(rèn)字體
使用系統(tǒng)默認(rèn)字體的主要原因是性能,系統(tǒng)字體的優(yōu)點在于它與當(dāng)前操作系統(tǒng)相匹配,因此它的文本展示效果必然也是令人舒適的。
2.9.2 兼顧中西:西文在前,中文在后
中文或者英文(西文)都要考慮到。由于大部分中文字體也帶有英文部分,但是英文部分又不怎么好看,并且英文字體中大多不包含中文。因此我們通常會先進(jìn)行英文字體的聲明,選擇最優(yōu)的英文字體,這樣不會影響到中文字體的選擇。
2.9.3 兼顧多操作系統(tǒng)
選擇字體的時候要考慮多操作系統(tǒng)。例如 macOS 下的很多中文字體在 Windows 都沒有預(yù)裝。為了保證 Mac 用戶的體驗,在定義中文字體的時候,先定義 Mac 用戶的中文字體,再定義 Windows 用戶的中文字體。
2.9.4 兼顧舊操作系統(tǒng):以字體族系列 serif 和 sans-serif 結(jié)尾
當(dāng)使用一些非常新的字體時,要考慮向下兼容,兼顧到一些極舊的操作系統(tǒng),使用字體族系列 serif 和 sans-serif 結(jié)尾總歸是不錯的選擇。
3. 可訪問性(A11Y)
可訪問性(accessibility,也被稱為 “A11Y”)在網(wǎng)站中屬于非常重要的一環(huán),但是大部分前端(其實應(yīng)該是設(shè)計、前端、產(chǎn)品)同學(xué)都忽視了它。
3.1 什么是可訪問性
傳統(tǒng)上我們認(rèn)為這只與殘障人士有關(guān),但提升網(wǎng)站的可訪問性也可以讓其他用戶群體(每個人)受益。
根據(jù)網(wǎng)頁內(nèi)容可訪問性準(zhǔn)則(即 “
Web Content Accessibility Guidelines (WCAG) 2.0”),Web 可訪問性有以下四個基礎(chǔ)性原則。
(1)可感知- 用文本替代非文本內(nèi)容
- 多媒體的字幕及其他替代物
- 內(nèi)容有多種呈現(xiàn)方式
- 內(nèi)容的看和聽更容易
(2)可操作- 可以通過鍵盤使用功能
- 用戶有充足的時間閱讀和使用內(nèi)容
- 內(nèi)容不要誘發(fā)癲癇和物理反應(yīng)
- 用戶可以方便地導(dǎo)航、找到內(nèi)容并確認(rèn)自己在哪里
- 用戶可以使用除鍵盤外的不同輸入方式
(3)可理解- 文本容易閱讀和理解
- 內(nèi)容以可預(yù)測的方式出現(xiàn)和操作
- 用戶可以得到幫忙,以避免和糾正錯誤
(4)健壯性- 健壯的內(nèi)容和可靠的解釋
- 內(nèi)容與現(xiàn)在和未來的用戶工具兼容
- 在各個平臺和環(huán)境中都能正確地展示
我潛伏在一個叫無障礙設(shè)計小組的群里,其中包含了很多無障礙設(shè)計師以及患有一定程度視覺、聽力、行動障礙的用戶,他們在群里經(jīng)常會表達(dá)出一個觀點,就是國內(nèi)的大部分 Web 網(wǎng)站及 App 基本沒有考慮過殘障人士的使用(或者可訪問性做得很差),非常令人揪心。
尤其在一些重交互、重邏輯的網(wǎng)站中,我們需要從高可訪問性的角度考慮用戶的使用習(xí)慣、使用場景。比如:假設(shè)用戶沒有鼠標(biāo),僅僅使用鍵盤,能否順暢使用我們的網(wǎng)站?
假設(shè)用戶沒有鼠標(biāo),這個真不一定是針對殘障人士。很多情況下,用戶拿鼠標(biāo)的手可能在干其他事情,比如在吃東西;又或者在 To B 類的業(yè)務(wù),如超市收銀、倉庫收貨,很可能用戶拿鼠標(biāo)的手操作著其他設(shè)備(掃碼槍)等等。
本文不會專門闡述無障礙設(shè)計的方方面面,只是從一些我覺得前端工程師需要關(guān)注的,并且僅需要花費(fèi)少量代價就能做好的一些無障礙設(shè)計細(xì)節(jié)。記住,
無障礙設(shè)計對所有人都更友善。
3.2 色彩對比度
顏色,也是我們天天需要打交道的屬性。大部分視覺正常的用戶可能對頁面的顏色敏感度還沒那么高。但是對于一小部分色弱、色盲用戶,他們對網(wǎng)站的顏色會更加敏感,不好的設(shè)計會給他們訪問網(wǎng)站帶來極大的不便。
3.2.1 什么是色彩對比度
是否曾關(guān)心過頁面內(nèi)容的展示,使用的顏色是否恰當(dāng)?色弱、色盲用戶能否正??辞鍍?nèi)容?良好的色彩使用,在任何時候都是有益的,而且不僅僅局限于色弱、色盲用戶。在戶外使用手機(jī),陽光很強(qiáng)看不清時,符合無障礙標(biāo)準(zhǔn)的高清晰度、高對比度文字就更容易閱讀。
這里引入了一個概念——
色彩對比度。簡單地說,就是兩種顏色在亮度(brightness)上的差別。運(yùn)用到我們的頁面上,大多數(shù)的情況就是背景色(background-color)與內(nèi)容顏色(color)的對比差異。
“最權(quán)威的互聯(lián)網(wǎng)無障礙規(guī)范——
WCAG AA 規(guī)范規(guī)定,所有重要內(nèi)容的色彩對比度需要達(dá)到 4.5:1 或以上(字號大于 18 號時達(dá)到 3:1 或以上),才算擁有較好的可讀性。”
看看下面這張圖:
很明顯,對比度由低到高。前兩個例子,別說視障用戶,正常用戶都已經(jīng)很難看得清了。
當(dāng)然,也會存在一些特例,譬如輸入框的
placeholder
、按鈕的禁用狀態(tài)等等。因此,在網(wǎng)頁重構(gòu)的過程中,我們需要盡可能遵循這個規(guī)范。但又不是盲目遵循,導(dǎo)致毫無回旋余地。
3.2.2 檢查色彩對比度的工具
Chrome 瀏覽器從很早開始,就已經(jīng)支持檢查元素的色彩對比度了。以 WMS 頁面中的一個 Table Header 為例,我們可以去檢查一些無法直觀界定是否達(dá)到標(biāo)準(zhǔn)的文字:
審查元素,分別可以看到當(dāng)前文字與背景的對比度。下述結(jié)果表示,這個對比度是沒有問題的:
當(dāng)然,我們的頁面上也會存在這樣的面包屑導(dǎo)航:
可以看到,色彩對比度沒有達(dá)到標(biāo)準(zhǔn)的部分,被用黃色嘆號標(biāo)識了出來。
除此之外,在審查元素的 Style 界面的取色器,改變顏色,也能直觀地看到當(dāng)前的色彩對比度:
3.2.3 不要單純依賴顏色
為了保證無障礙的準(zhǔn)確性,應(yīng)當(dāng)確保你沒有完全依賴顏色來展示系統(tǒng)不同層級的關(guān)鍵信息。
看看下面這個例子:
本來我們期待利用綠色和紅色來表達(dá)正確與錯誤,但是對于部分視覺障礙用戶,他可能根本感受不到這個提示。
正確的做法是,使用必要的文字和圖標(biāo)進(jìn)行說明:
因此在實際應(yīng)用中,我們需要利用能傳達(dá)準(zhǔn)確信息的圖標(biāo)配合文字描述去表達(dá),譬如 WMS 登錄錯誤頁面:
3.3 焦點響應(yīng)
類似百度、谷歌的首頁,進(jìn)入頁面后會默認(rèn)讓輸入框獲得焦點:
并非所有的有輸入框的頁面都需要進(jìn)入頁面后進(jìn)行聚焦,但是焦點能夠讓用戶非常明確地知道當(dāng)前自己在哪,需要做些什么。尤其是對于無法操作鼠標(biāo)的用戶來說。
頁面上可以聚焦的元素,稱為
可聚焦元素,獲得焦點的元素,則會觸發(fā)該元素的
focus
事件。對應(yīng)地,也會觸發(fā)該元素的
:focus
偽類。
瀏覽器通常會使用元素的
:focus
偽類,給元素添加一層邊框,告訴用戶當(dāng)前的獲焦元素在哪里。
我們可以通過鍵盤的
Tab
鍵,進(jìn)行焦點的切換。而獲焦元素則可以通過元素的
:focus
偽類的樣式,告訴用戶當(dāng)前焦點位置。
當(dāng)然,除了 Tab
鍵之外,對于一些多輸入框、選擇框的表單頁面,我們也應(yīng)該想著如何簡化用戶的操作,例如用戶按回車鍵時自動前進(jìn)到下一字段。一般而言,用戶必須執(zhí)行的觸按越少,體驗越佳。
下面的截圖,完全由鍵盤操作完成:
通過元素的
:focus
偽類以及鍵盤 Tab 鍵切換焦點,用戶可以非常順暢地在脫離鼠標(biāo)的情況下,對頁面的焦點切換及操作。
然而,在許多
reset.css
中,經(jīng)常能看到這樣一句 CSS 樣式代碼,為了樣式的統(tǒng)一,消除了可聚焦元素的
:focus
偽類:
:focus { outline: 0;}
我們給上述操作的代碼。也加上這樣一句代碼,
全程再用鍵盤操作一下:
除了在
input
框有光標(biāo)提示,當(dāng)使用
Tab
進(jìn)行焦點切換到
select
或者到
button
時,由于沒有了
:focus
樣式,用戶會感到迷茫,不知道頁面的焦點現(xiàn)在處于何處。
3.3.1 保證非鼠標(biāo)用戶體驗,合理運(yùn)用 :focus-visible
造成上述結(jié)果很重要的一個原因在于,
:focus
偽類不論用戶在使用鼠標(biāo)還是使用鍵盤,只要元素獲焦,就會觸發(fā)。
而其本身的默認(rèn)樣式又不太能被產(chǎn)品或者設(shè)計接受,導(dǎo)致了很多人會在焦點元素觸發(fā)
:focus
偽類時,通過改變 border 的顏色或者其他一些方式替代或者直接禁用。而這樣做,從可訪問性的角度來看,對于非鼠標(biāo)用戶,無疑是災(zāi)難性的。
基于此,在
W3 CSS selectors-4 規(guī)范中,新增了一個非常有意思的
:focus-visible
偽類。這個選擇器可以有效地根據(jù)用戶的輸入方式(鼠標(biāo)或是鍵盤)展示不同形式的焦點。
有了這個偽類,當(dāng)用戶使用鼠標(biāo)操作可聚焦元素時,就可以做到不展示
:focus
樣式或者讓其表現(xiàn)較弱;而當(dāng)用戶使用鍵盤操作焦點時,利用
:focus-visible
,讓可獲焦元素獲得一個較強(qiáng)的表現(xiàn)樣式。
看個簡單的 Demo:
<button>Test 1</button>
button:active { background: #eee;}button:focus { outline: 2px solid red;}
使用鼠標(biāo)點擊:
可以看到,使用鼠標(biāo)點擊的時候,觸發(fā)了元素的 :active 偽類,也觸發(fā)了 :focus 偽類,不太美觀。但是如果設(shè)置了 outline: none 又會使鍵盤用戶的體驗非常糟糕。嘗試使用 :focus-visible 偽類改造一下:
button:active { background: #eee;}button:focus { outline: 2px solid red;}button:focus:not(:focus-visible) { outline: none;}
看看效果,分別是在鼠標(biāo)點擊 Button 和使用鍵盤控制焦點點擊 Button:
CodePen Demo - :focus-visible example可以看到,使用鼠標(biāo)點擊,不會觸發(fā)
:foucs
,只有當(dāng)鍵盤操作聚焦元素,使用
Tab
切換焦點時,
outline: 2px solid red
這段代碼才會生效。
這樣,我們就既保證了正常用戶的點擊體驗,也保證了一批無法使用鼠標(biāo)的用戶的焦點管理體驗。
值得注意的是,有同學(xué)會疑惑,這里為什么使用了
:not
這么繞的寫法而不是直接這樣寫呢:
button:focus { outline: unset;}button:focus-visible { outline: 2px solid red;}
為的是兼容不支持
:focus-visible
的瀏覽器,當(dāng)
:focus-visible
不兼容時,還是需要有
:focus
偽類的存在。
我們在實際的 WMS 重構(gòu)過程中,也會盡量保持這一點,讓用戶盡可能在非鼠標(biāo)操作下(僅僅使用鍵盤),也能使用我們的頁面,能做到基礎(chǔ)的焦點切換、回車響應(yīng)事件。
下圖是一個簡單的演示(僅僅使用鍵盤進(jìn)行頁面的操作,能夠知道當(dāng)前焦點在哪,可以回車觸發(fā)點擊):
3.3.2 使用 WAI-ARIA 規(guī)范增強(qiáng)語義:div 等非可獲焦元素模擬獲焦元素
還有一個非常需要注意的點。
現(xiàn)在很多前端同學(xué)在前端開發(fā)的過程中,喜歡使用非可獲焦元素模擬獲焦元素,例如:
- 使用
div
模擬 button
元素 - 使用
ul
模擬下拉列表 select
等等
當(dāng)下很多組件庫都是這樣做的,像是 element-ui 和 ant-design。
在使用非可獲焦元素模擬獲焦元素的時候,一定要注意,不僅僅只是外觀長得像就完事了,其行為表現(xiàn)也需要符合原本的
button
、
select
等可聚焦元素的性質(zhì),能夠體現(xiàn)元素的語義,能夠被聚焦,能夠通過 Tab 切換等等。
基于大量類似的場景,有了
WAI-ARIA 標(biāo)準(zhǔn)。它是一個為殘疾人士等提供無障礙訪問動態(tài)、可交互 Web 內(nèi)容的技術(shù)規(guī)范。
簡單來說,WAI-ARIA 提供了一些屬性,用于增強(qiáng)標(biāo)簽的語義及行為:
- 可以使用
tabindex
屬性控制元素是否可以聚焦,以及它是否/在何處參與順序鍵盤導(dǎo)航 - 可以使用
role
屬性,來標(biāo)識元素的語義及作用,譬如使用 <div id="saveChanges" tabindex="0" role="button">Save</div>
來模擬一個按鈕 - 還有大量的
aria-*
屬性,表示元素的屬性或狀態(tài),幫助我們進(jìn)一步地識別以及實現(xiàn)元素的語義化,優(yōu)化無障礙體驗
3.4 使用工具查看標(biāo)簽的語義
我們來看看 Github 頁面是如何定義一個按鈕的。以 Github Issues 頁面的 Edit 按鈕為例:
這一塊清晰地描述了這個按鈕在可訪問性相關(guān)的一些特性。比如
Contrast
(色彩對比度)、
Name
(按鈕的描述),是給屏幕閱讀器看到的;
Role
標(biāo)識是這個元素的屬性,它是一個按鈕,
Keyboard focusable
則表明能否被鍵盤的 Tab 按鈕捕獲。
3.5 分析使用非可聚焦元素模擬的按鈕
這里隨便選取了我們業(yè)務(wù)中一個使用 span 模擬按鈕的場景,是一個面包屑導(dǎo)航,點擊可進(jìn)行跳轉(zhuǎn):
HTML 代碼:
<span class="ssc-breadcrumb-item-link"> Inbound </span>
基本上可訪問性為零。作為一個按鈕,它不可被聚焦,無法被鍵盤用戶選中,沒有具體的語義,色彩對比度太低,可能視障用戶無法看清。并且,作為一個能進(jìn)行頁面跳轉(zhuǎn)的按鈕,它沒有
<a>
標(biāo)簽,沒有
href
屬性。
對于面包屑導(dǎo)航,我們可以不將它改造成
<a>
標(biāo)簽,但也需要做到最基本的一些可訪問性改造:
<span role="button" aria-label="goto inbound page" tabindex="0" class="ssc-breadcrumb-item-link"> Inbound </span>
不要忘了再改一下顏色,達(dá)到最低色彩對比度以上,再看看:
這樣,一個最最最基本的,滿足最低可訪問性需求的按鈕算是勉強(qiáng)達(dá)標(biāo)。當(dāng)然,這個按鈕可以再更進(jìn)一步進(jìn)行改造,涉及了更深入的可訪問性知識,本文不詳細(xì)展開。
3.6 分析組件庫的可訪問性
最后,我們來看看常用的 ant-design 在提升可訪問性上的一些相關(guān)功能。
以 Select 選擇框組件為例,ant-design 利用了大量的 WAI-ARIA 屬性,使得用 div 模擬的下拉框不僅僅在表現(xiàn)上符合一個下拉框,在語義、行為上都符合一個下拉框。
看看使用 div 模擬下拉框的 DOM 部分:
再看看在交互體驗上:
上述操作完全在鍵盤下完成,看著平平無奇,實際上組件庫在正常響應(yīng)可獲焦元素切換的同時,給用 div 模擬的
select
加了很多鍵盤事件的響應(yīng),可以利用回車、上下鍵等對可選項進(jìn)行選擇。其實下了很多功夫。
對于可訪問性相關(guān)的內(nèi)容非常多,本文無法一一展開,這里有一份簡單的指南:
- 通過 Web 內(nèi)容無障礙指南(WCAG 2.0)了解可訪問性涉及的內(nèi)容;
- 通過 WAI-ARIA 了解如何改造頁面;
- 不斷了解最新的規(guī)范,通過瀏覽器最新的功能持續(xù)增強(qiáng)可訪問性。
4. 總結(jié)
本文從
頁面展示、交互細(xì)節(jié)、可訪問性三個大方面入手,列舉了一些在實際開發(fā)過程中積攢的有益經(jīng)驗。雖然不夠全面,主要是一些可能有用但是容易被忽視的點,也算是一個不錯的查缺補(bǔ)漏小指南。
提升
用戶體驗并非易事,但也不難:
- 頁面呈現(xiàn) + 注重細(xì)節(jié)的交互設(shè)計 + 完善的可訪問性 + 性能(性能本文沒有過多提及) = 良好的用戶體驗;
- 用戶體驗是可以被提升的,而且并不難;
- 良好的用戶體驗設(shè)計,是產(chǎn)品開發(fā)每一個環(huán)節(jié)共同努力的結(jié)果;
- 提升用戶體驗也不是能夠一蹴而就的,在不同的細(xì)節(jié)發(fā)力,積少成多。
以上觀點和想法可能有一些理解存在問題,一些概念沒有解讀到位,也希望大家參與交流并指正。
參考資料
- WAI-ARIA basics
- WAI-ARIA 1.1
- Web 中的焦點管理
- 無障礙功能
- 功能性動畫設(shè)計:優(yōu)秀的轉(zhuǎn)場效果
- 前端基礎(chǔ)知識概述
- 圖片加載失敗后 CSS 樣式處理最佳實踐
- 你所不知道的 CSS 動畫技巧與細(xì)節(jié)
- Web 動畫原則及技巧淺析
- 如何設(shè)計產(chǎn)品的空白頁面?
- 助你輕松做好無障礙的 15 個 UI 設(shè)計工具推薦
- Improve Your UI With Winning & Losing A/B Tests
本文作者
Coco,前端開發(fā)工程師,來自 Shopee 供應(yīng)鏈倉儲管理(Warehouse management system, WMS)團(tuán)隊。
加入我們
Shopee WMS 支撐著 Shopee 所有自營業(yè)務(wù)和越來越多 Shopee 平臺商家的倉儲業(yè)務(wù),是供應(yīng)鏈核心系統(tǒng)之一,目前服務(wù)范圍覆蓋整個東南亞市場,支撐日百萬級別包裹出庫履約。我們致力于打造一套能面向不同市場不同文化能差異化操作的,支持藥品、生鮮等多垂直領(lǐng)域的,未來能支撐日千萬級包裹出庫履約的倉儲系統(tǒng);我們持續(xù)優(yōu)化流程、算法、升級系統(tǒng)架構(gòu),引入自動化設(shè)備,以達(dá)到降本增效的目的,同時使某些新的商業(yè)模式成為可能。
目前團(tuán)隊大量崗位持續(xù)招聘中,海量 HC 涵蓋后端、前端、測試、產(chǎn)品等,感興趣的同學(xué)可將簡歷發(fā)送至 kingsley.huang@shopee.com (亦可進(jìn)行咨詢,注明來自 Shopee 技術(shù)博客)。
關(guān)鍵詞:提升,實踐,設(shè)計,體驗,用戶