新聞中心
在這篇文章中,我想和大家分享我是如何為 web 原型化一個(gè) Sidenav 組件的,這個(gè)組件是響應(yīng)式的,有狀態(tài)的,支持鍵盤(pán)導(dǎo)航,可以使用和不使用 Javascript,并且可以跨瀏覽器工作。

10年積累的網(wǎng)站制作、成都做網(wǎng)站經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問(wèn)題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站制作后付款的網(wǎng)站建設(shè)流程,更有高陵免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
構(gòu)建一個(gè)響應(yīng)式導(dǎo)航系統(tǒng)是很困難的。有些用戶使用鍵盤(pán),有些用戶使用強(qiáng)大的臺(tái)式機(jī),還有一些用戶使用小型移動(dòng)設(shè)備訪問(wèn)。每個(gè)訪問(wèn)者都應(yīng)該能夠打開(kāi)和關(guān)閉菜單。
桌面到移動(dòng)設(shè)備響應(yīng)式布局演示
用了哪些技術(shù)
在這次組件探索中,我很高興地結(jié)合了一些關(guān)鍵的網(wǎng)絡(luò)平臺(tái)特性:
- 偽類
- CSS Grid
- transforms
- 媒體查詢和用戶偏好 CSS
- 用戶增強(qiáng)體驗(yàn)
我的解決方案只有一個(gè)側(cè)邊欄,只有在“移動(dòng)”視口為540px 或更小時(shí)才能切換。540px 將是我們?cè)谝苿?dòng)交互式布局和靜態(tài)桌面布局之間切換的斷點(diǎn)。
偽類
一個(gè) 鏈接將 url 散列設(shè)置為 #sidenav-open,另一個(gè)設(shè)置為 empty('')。最后,一個(gè)元素具有匹配散列的 id:
點(diǎn)擊這些鏈接會(huì)改變我們網(wǎng)頁(yè) URL 的散列狀態(tài),然后用一個(gè)偽類來(lái)顯示和隱藏 Sidenav:
- @media (max-width: 540px) {
- #sidenav-open {
- visibility: hidden;
- }
- #sidenav-open:target {
- visibility: visible;
- }
- }
CSS Grid
在過(guò)去,我只使用絕對(duì)或固定位置 Sidenav 布局和組件。不過(guò),使用網(wǎng)格區(qū)域語(yǔ)法,可以為同一行或列分配多個(gè)元素。
Stacks
主要的布局元素 #sidenav-container 是一個(gè)網(wǎng)格,它創(chuàng)建了 1 行和 2 列,其中 1 列被命名為 stack。當(dāng)空間受到限制時(shí),CSS 會(huì)將所有
- #sidenav-container {
- display: grid;
- grid: [stack] 1fr / min-content [stack] 1fr;
- min-height: 100vh;
- }
- @media (max-width: 540px) {
- #sidenav-container > * {
- grid-area: stack;
- }
- }
菜單背景
- #sidenav-open {
- display: grid;
- grid-template-columns: [nav] 2fr [escape] 1fr;
- }
調(diào)整 2fr 和 1fr,找到你喜歡的菜單覆蓋和負(fù)空間關(guān)閉按鈕的比例。
3D transforms
我們的布局現(xiàn)在是堆疊在一個(gè)移動(dòng)視口大小。除非我添加一些新的樣式,否則它將默認(rèn)覆蓋我們的文章。下面是一些我正在努力實(shí)現(xiàn)的用戶體驗(yàn):
- 動(dòng)畫(huà)打開(kāi)和關(guān)閉;
- 只有在用戶同意的情況下才使用動(dòng)畫(huà);
- 鍵盤(pán)焦點(diǎn)不會(huì)進(jìn)入屏幕以外的元素;
當(dāng)我開(kāi)始實(shí)現(xiàn)動(dòng)作動(dòng)畫(huà)的時(shí)候,我想先從可訪問(wèn)性開(kāi)始。
無(wú)障礙運(yùn)動(dòng)
不是每個(gè)人都想要幻燈片移動(dòng)的體驗(yàn)。在我們的解決方案中,這個(gè)首選項(xiàng)是通過(guò)調(diào)整媒體查詢中的 -- duration CSS 變量來(lái)實(shí)現(xiàn)的。此媒體查詢值表示用戶的操作系統(tǒng)對(duì)移動(dòng)的偏好(如果可用)。
- #sidenav-open {
- --duration: .6s;
- }
- @media (prefers-reduced-motion: reduce) {
- #sidenav-open {
- --duration: 1ms;
- }
- }
現(xiàn)在,當(dāng)我們的 sidenav 滑動(dòng)打開(kāi)和關(guān)閉,如果用戶喜歡減少運(yùn)動(dòng),我立即移動(dòng)元素進(jìn)入視圖,保持沒(méi)有運(yùn)動(dòng)的狀態(tài)。
Transition, transform, translate
Sidenav 默認(rèn)是退出狀態(tài)的。為了將移動(dòng)設(shè)備上 Sidenav 的默認(rèn)狀態(tài)設(shè)置為屏幕外狀態(tài),我將元素的位置設(shè)置為:
- transform: translateX (- 110vw);
注意,我在典型的屏幕外代碼 -100vw 中添加了10vw,以確保當(dāng) sidenav 隱藏時(shí),它的盒子陰影不會(huì)窺視主視圖。
- @media (max-width: 540px) {
- #sidenav-open {
- visibility: hidden;
- transform: translateX(-110vw);
- will-change: transform;
- transition:
- transform var(--duration) var(--easeOutExpo),
- visibility 0s linear var(--duration);
- }
- }
當(dāng) #sidenav 元素匹配為 :target 時(shí),將 translateX() 位置設(shè)置為 0。當(dāng) URL 哈希值變化的時(shí)候,觀察到元素會(huì)從 -110vw 的位置滑動(dòng)到 0 的位置。
- @media (max-width: 540px) {
- #sidenav-open:target {
- visibility: visible;
- transform: translateX(0);
- transition: transform var(--duration) var(--easeOutExpo);
- }
- }
過(guò)渡時(shí)期的可見(jiàn)性
現(xiàn)在的目標(biāo)是屏幕閱讀器看不到菜單,這樣系統(tǒng)就不會(huì)把焦點(diǎn)放在屏幕外的菜單上。我通過(guò)在: 目標(biāo)更改時(shí)設(shè)置可見(jiàn)性轉(zhuǎn)換來(lái)實(shí)現(xiàn)這一點(diǎn)。
- 進(jìn)入時(shí),請(qǐng)勿過(guò)渡可見(jiàn)性;立刻可見(jiàn),因此我可以看到元素滑入并接受焦點(diǎn)。
- 退出時(shí),給他加一個(gè)延遲到過(guò)渡效果;
可訪問(wèn)性 UX 增強(qiáng)
鏈接
此解決方案依賴于更改 URL 以便管理狀態(tài)。當(dāng)然,這里應(yīng)該使用 元素,它可以免費(fèi)獲得一些很好的可訪問(wèn)性特性。讓我們用清楚表達(dá)意圖的標(biāo)簽來(lái)裝飾我們的交互式元素。
現(xiàn)在我們的主要交互按鈕清楚地表明了鼠標(biāo)和鍵盤(pán)的意圖。
- :is(:hover, :focus)
這個(gè)方便的 CSS 函數(shù)式偽選擇器可以讓我們通過(guò)分享焦點(diǎn)快速地包容我們的懸停樣式。
- .hamburger:is(:hover, :focus) svg > line {
- stroke: hsl(var(--brandHSL));
- }
加上點(diǎn) JS
鍵盤(pán)上的 Escape 鍵應(yīng)該關(guān)閉菜單,對(duì)嗎? 讓我們把它實(shí)現(xiàn):
- const sidenav = document.querySelector('#sidenav-open');
- sidenav.addEventListener('keyup', event => {
- if (event.code === 'Escape') document.location.hash = '';
- });
下一個(gè)代碼片段幫助我們將注意力集中在打開(kāi)或關(guān)閉按鈕上。我想讓切換變得簡(jiǎn)單。
- sidenav.addEventListener('transitionend', e => {
- const isOpen = document.location.hash === '#sidenav-open';
- isOpen
- ? document.querySelector('#sidenav-close').focus()
- : document.querySelector('#sidenav-button').focus();
- })
當(dāng) Sidenav 打開(kāi)時(shí),集中關(guān)閉按鈕。當(dāng) Sidenav 關(guān)閉時(shí),集中打開(kāi)按鈕。我通過(guò)在 JS 中的元素上調(diào)用 focus() 來(lái)實(shí)現(xiàn)這一點(diǎn)。
網(wǎng)頁(yè)標(biāo)題:一個(gè)側(cè)邊欄導(dǎo)航組件實(shí)現(xiàn)思路
當(dāng)前URL:http://fisionsoft.com.cn/article/cddcedp.html


咨詢
建站咨詢
