hamburger组件_一个侧边栏导航组件实现思路
翻譯:布蘭
作者:Adam Argyle
來源:https://web.dev/building-a-sidenav-component/
在這篇文章中,我想和大家分享我是如何為 web 原型化一個 Sidenav 組件的,這個組件是響應(yīng)式的,有狀態(tài)的,支持鍵盤導(dǎo)航,可以使用和不使用 Javascript,并且可以跨瀏覽器工作。
構(gòu)建一個響應(yīng)式導(dǎo)航系統(tǒng)是很困難的。有些用戶使用鍵盤,有些用戶使用強大的臺式機,還有一些用戶使用小型移動設(shè)備訪問。每個訪問者都應(yīng)該能夠打開和關(guān)閉菜單。
桌面到移動設(shè)備響應(yīng)式布局演示用了哪些技術(shù)
在這次組件探索中,我很高興地結(jié)合了一些關(guān)鍵的網(wǎng)絡(luò)平臺特性:
- 偽類
- CSS Grid
- transforms
- 媒體查詢和用戶偏好 CSS
- 用戶增強體驗
我的解決方案只有一個側(cè)邊欄,只有在“移動”視口為540px 或更小時才能切換。540px 將是我們在移動交互式布局和靜態(tài)桌面布局之間切換的斷點。
偽類
一個 鏈接將 url 散列設(shè)置為 #sidenav-open,另一個設(shè)置為 empty('')。最后,一個元素具有匹配散列的 id:
<a?href="#sidenav-open"?id="sidenav-button"?title="Open?Menu"?aria-label="Open?Menu"><a?href="#"?id="sidenav-close"?title="Close?Menu"?aria-label="Close?Menu">a>
<aside?id="sidenav-open">aside>
點擊這些鏈接會改變我們網(wǎng)頁 URL 的散列狀態(tài),然后用一個偽類來顯示和隱藏 Sidenav:
@media?(max-width:?540px)?{????#sidenav-open?{
????????visibility:?hidden;
????}
????
????#sidenav-open:target?{
????????visibility:?visible;
????}
}
CSS Grid
在過去,我只使用絕對或固定位置 Sidenav 布局和組件。不過,使用網(wǎng)格區(qū)域語法,可以為同一行或列分配多個元素。
Stacks
主要的布局元素 #sidenav-container 是一個網(wǎng)格,它創(chuàng)建了 1 行和 2 列,其中 1 列被命名為 stack。當(dāng)空間受到限制時,CSS 會將所有 元素的子元素賦給同一個網(wǎng)格名稱,將所有元素放在同一個空間中,創(chuàng)建一個堆棧。
#sidenav-container?{????display:?grid;
????grid:?[stack]?1fr?/?min-content?[stack]?1fr;
????min-height:?100vh;
}
@media?(max-width:?540px)?{
????#sidenav-container?>?*?{
????????grid-area:?stack;
????}
}
菜單背景
是包含側(cè)邊導(dǎo)航的動畫元素。它有兩個子元素: 導(dǎo)航容器 命名為 [nav] ,背景幕布 命名為 [escape],用于關(guān)閉菜單。
#sidenav-open?{????display:?grid;
????grid-template-columns:?[nav]?2fr?[escape]?1fr;
}
調(diào)整 2fr 和 1fr,找到你喜歡的菜單覆蓋和負(fù)空間關(guān)閉按鈕的比例。
3D transforms
我們的布局現(xiàn)在是堆疊在一個移動視口大小。除非我添加一些新的樣式,否則它將默認(rèn)覆蓋我們的文章。下面是一些我正在努力實現(xiàn)的用戶體驗:
- 動畫打開和關(guān)閉;
- 只有在用戶同意的情況下才使用動畫;
- 鍵盤焦點不會進(jìn)入屏幕以外的元素;
當(dāng)我開始實現(xiàn)動作動畫的時候,我想先從可訪問性開始。
無障礙運動
不是每個人都想要幻燈片移動的體驗。在我們的解決方案中,這個首選項是通過調(diào)整媒體查詢中的 -- duration CSS 變量來實現(xiàn)的。此媒體查詢值表示用戶的操作系統(tǒng)對移動的偏好(如果可用)。
#sidenav-open?{????--duration:?.6s;
}
@media?(prefers-reduced-motion:?reduce)?{
????#sidenav-open?{
????????--duration:?1ms;
????}
}
現(xiàn)在,當(dāng)我們的 sidenav 滑動打開和關(guān)閉,如果用戶喜歡減少運動,我立即移動元素進(jìn)入視圖,保持沒有運動的狀態(tài)。
Transition, transform, translate
Sidenav 默認(rèn)是退出狀態(tài)的。為了將移動設(shè)備上 Sidenav 的默認(rèn)狀態(tài)設(shè)置為屏幕外狀態(tài),我將元素的位置設(shè)置為:
transform:?translateX?(-?110vw);注意,我在典型的屏幕外代碼 -100vw 中添加了10vw,以確保當(dāng) sidenav 隱藏時,它的盒子陰影不會窺視主視圖。
@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 時,將 translateX() 位置設(shè)置為 0。當(dāng) URL 哈希值變化的時候,觀察到元素會從 -110vw 的位置滑動到 0 的位置。
@media?(max-width:?540px)?{????#sidenav-open:target?{
????????visibility:?visible;
????????transform:?translateX(0);
????????transition:?transform?var(--duration)?var(--easeOutExpo);
????}
}
過渡時期的可見性
現(xiàn)在的目標(biāo)是屏幕閱讀器看不到菜單,這樣系統(tǒng)就不會把焦點放在屏幕外的菜單上。我通過在: 目標(biāo)更改時設(shè)置可見性轉(zhuǎn)換來實現(xiàn)這一點。
- 進(jìn)入時,請勿過渡可見性;立刻可見,因此我可以看到元素滑入并接受焦點。
- 退出時,給他加一個延遲到過渡效果;
可訪問性 UX 增強
鏈接
此解決方案依賴于更改 URL 以便管理狀態(tài)。當(dāng)然,這里應(yīng)該使用 元素,它可以免費獲得一些很好的可訪問性特性。讓我們用清楚表達(dá)意圖的標(biāo)簽來裝飾我們的交互式元素。
<a?href="#"?id="sidenav-close"?title="Close?Menu"?aria-label="Close?Menu">a><a?href="#sidenav-open"?id="sidenav-button"?class="hamburger"?title="Open?Menu"?aria-label="Open?Menu">
????<svg>...svg>
a>
現(xiàn)在我們的主要交互按鈕清楚地表明了鼠標(biāo)和鍵盤的意圖。
:is(:hover,?:focus)這個方便的 CSS 函數(shù)式偽選擇器可以讓我們通過分享焦點快速地包容我們的懸停樣式。
.hamburger:is(:hover,?:focus)?svg?>?line?{????stroke:?hsl(var(--brandHSL));
}
加上點 JS
鍵盤上的 Escape 鍵應(yīng)該關(guān)閉菜單,對嗎? 讓我們把它實現(xiàn):
const?sidenav?=?document.querySelector('#sidenav-open');sidenav.addEventListener('keyup',?event?=>?{
????if?(event.code?===?'Escape')?document.location.hash?=?'';
});
下一個代碼片段幫助我們將注意力集中在打開或關(guā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 打開時,集中關(guān)閉按鈕。當(dāng) Sidenav 關(guān)閉時,集中打開按鈕。我通過在 JS 中的元素上調(diào)用 focus() 來實現(xiàn)這一點。
總結(jié)
以上是生活随笔為你收集整理的hamburger组件_一个侧边栏导航组件实现思路的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 主要经济体一季度经济增长情况,多数表现不
- 下一篇: 储蓄国债迎来一个变化,今天起买国债不用去