如何使用 Chakra UI 和 Nuxt.js 構建可訪問的前端應用程序

已發表: 2022-03-10
快速總結↬在本文中,我們將研究如何使用 Chakra UI 和 NuxtJS 構建可訪問的前端應用程序。 為了繼續學習,您應該熟悉將漸進式前端框架 Vue.js 與 Nuxt 一起使用。 如果沒有,請參閱 Vue.js 和 NuxtJS 文檔以開始使用。

對於許多人來說,網絡是他們日常生活中必不可少的一部分。 他們在工作、家中甚至在路上都使用它。 網絡無障礙意味著殘障人士可以平等地使用網絡。 因此,對於在 Web 上構建的開發人員和組織而言,在其應用程序中構建包容性和可訪問性至關重要。

為了使 Web 更易於訪問,您必須在應用程序中實施一些最佳實踐和標準,例如遵守以下內容:

  • 第 508 條;
  • 輔助技術法;
  • 美國殘疾人法案(ADA);
  • WCAG 2.0(A 和 AA 指南);
  • BBC 移動無障礙指南;
  • WAI - ARIA (Web訪問性倡議——可訪問豐富互聯網應用)實踐。

當您將項目截止日期和作為開發人員必須處理的其他限制因素考慮在內時,學習實施這些標準似乎是一項艱鉅的任務。 鑑於此,讓我向您介紹一個 UI 設計系統,該系統旨在幫助您使您的 Web 應用程序易於訪問。

脈輪用戶界面

Chakra UI 是由 Segun Adebayo 創建的設計系統和 UI 框架。 它的創建考慮了簡單性、模塊化、可組合性和可訪問性。 Chakra UI 為您提供了創建可訪問的前端應用程序所需的所有構建塊。

注意雖然 Chakra UI 在底層依賴於 CSS-in-JS,但您無需了解它即可使用該庫。

儘管該框架最初是為 React 創建的,但 Jonathan Bakebwa 率先將移植到 Vue。 因此,Vuejs/NuxtJS 開發人員現在可以利用 Chakra UI 創建可訪問的 Web 應用程序。

脈輪用戶界面的特點

Chakra UI 的創建考慮了以下原則:

  • 風格道具
    Chakra UI 可以通過使用 props 來設置組件樣式或覆蓋它們的樣式。 這減少了對樣式表或內聯樣式的需求。 Chakra UI 通過在後台使用 Styled Systems 實現了這種級別的靈活性。
  • 作品
    Chakra UI 中的組件已被分解為具有最少道具的較小部分,以保持較低的複雜性,並將它們組合在一起。 這將確保樣式和功能是靈活和可擴展的。 例如,您可以使用CBoxCPseudoBox組件來創建新組件。
  • 無障礙
    Chakra UI 組件遵循 WAI-ARIA 指南規範並具有正確的 aria-* 屬性。 您還可以在名為accessibility.md的文件中找到每個編寫組件的可訪問性報告。 請參閱CAccordion組件的可訪問性報告。
  • 主題化
    Chakra UI 使您能夠在整個應用程序中的任何組件上輕鬆引用主題中的值。
  • 暗模式支持
    Chakra UI 中的大多數組件都是開箱即用的暗模式兼容。

Chakra UI 如何支持可訪問性

創建 Chakra UI 背後的核心原則之一是可訪問性。 考慮到這一點,Chakra UI 中的所有組件都是開箱即用的,通過提供以下功能支持可訪問性:

  • 鍵盤導航——對有運動技能障礙的用戶有用,
  • 焦點管理,
  • 屏幕閱讀器所需的 aria-* 屬性,
  • 模態對話框的焦點捕獲和恢復。
跳躍後更多! 繼續往下看↓

Chakra UI 和 Nuxt 入門

注意要將 Chakra UI 與 Vue.js 一起使用,請參閱入門指南。

對於我們的演示項目,我們將構建Chakra-ui 瀏覽器——一個可訪問的單頁 Web 應用程序,用於搜索 Chakra UI 組件。

  • 在 Netlify 上查看實時項目 →

Chakra-ui Explorer 入門

假設你已經安裝了 NPM,通過運行創建一個新的 Nuxt 應用程序:

 $ npx create-nuxt-app chakra-ui-explorer

或者,如果您更喜歡使用紗線,請運行:

 $ yarn create nuxt-app chakra-ui-explorer

按照安裝提示完成創建 Nuxt 應用程序。

設置脈輪 UI

Chakra UI 使用 Emotion 來處理組件樣式。 因此,要開始使用 Chakra UI,您需要將 Chakra UI 與 Emotion 作為對等依賴項一起安裝。 對於這個項目,我們將為 Chakra UI 和 Emotion 使用官方 Nuxt 模塊,這將減少開始使用 Chakra UI 時的摩擦。 讓我們通過運行以下命令將它們添加到我們的項目中:

 npm i @chakra-ui/nuxt @nuxtjs/emotion

注意@nuxtjs/emotion允許在服務器構建中生成和注入組件樣式。

安裝這兩個模塊後,您需要在模塊數組選項下的nuxt.config.js文件中註冊它們:

 // nuxt.config.js modules: ['@chakra-ui/nuxt', '@nuxtjs/emotion'],

要完成 Chakra UI 的設置過程,我們需要在layouts/中觸摸我們的默認佈局組件,並從 Chakra UI 添加CThemeProviderCColorModeProviderCReset組件。

建議您使用CReset組件以確保 Chakra UI 提供的所有組件都能正常工作。

CThemeProvider組件將使您的主題可用於應用程序的每個部分,而CColorModeProvider組件負責處理應用程序的顏色模式,該模式可以處於以下兩種狀態之一:淺色或深色。 最後, CReset組件將刪除所有瀏覽器默認樣式。

讓我們在layouts/default.vue中添加上述組件。 在我們的模板部分,讓我們添加:

 <!-- layouts/default.vue --> <template> <div class="container"> <c-theme-provider> <c-color-mode-provider> <c-box as="section"> <c-reset /> <nuxt /> </c-box> </c-color-mode-provider> </c-theme-provider> </div> </template>

然後在我們的腳本部分,我們將像這樣導入和註冊組件:

 <script> import { CThemeProvider, CColorModeProvider, CReset, CBox } from '@chakra-ui/vue' export default { name: 'DefaultLayout', components: { CThemeProvider, CColorModeProvider, CReset, CBox } } </script>

您的default.vue佈局組件應如下所示:

 <template> <div class="container"> <c-theme-provider> <c-color-mode-provider> <c-box as="section"> <c-reset /> <nuxt /> </c-box> </c-color-mode-provider> </c-theme-provider> </div> </template> <script> import { CThemeProvider, CColorModeProvider, CReset, CBox } from '@chakra-ui/vue' export default { name: 'DefaultLayout', components: { CThemeProvider, CColorModeProvider, CReset, CBox } } </script>

注意請注意,我將<c-reset /><nuxt />組件都包裝在一個c-box組件中。

設置您的應用程序主題

Chakra UI 允許您為應用程序設置主題。 “主題”是指應用程序的調色板、類型比例、字體堆棧、斷點、邊框半徑值等的設置。 由於顏色和對比度是可訪問性的重要組成部分,因此使用易於感知的顏色非常重要。

開箱即用的 Chakra UI 附帶一個默認主題對象,可滿足您應用程序在顏色、字體等方面的大部分需求。 默認主題的設置考慮了對比度,可以輕鬆切換顏色模式(稍後會詳細介紹)。

但是,Chakra UI 允許您擴展或完全替換默認主題。 這可以通過接受基於樣式系統主題規範的主題對象來實現。

主題對像中的值會自動在您的應用程序中使用。 例如,在theme.colors中指定的顏色可以被組件中的colorborderColorbackgroundColorfillstrokestyle屬性引用。

要個性化您的應用程序,您可以覆蓋 Chakra UI 提供的默認主題或在其中設置新值。 為此,Chakra UI Nuxt 模塊公開了一個chakra對象,該對象將接受一個extendTheme屬性,該屬性接受一個對象。 賦予extendTheme的對象將遞歸合併到 Chakra UI 默認主題對象。 讓我們將我們的品牌調色板添加到 Chakra,以便我們可以在我們的應用程序中使用它。

注意Chakra UI 建議使用從 50 到 900 的鍵將調色板添加到主題的顏色對像中。您可以使用 Coolors 和 palx 等 Web 工具來生成這些調色板。

對於我們的演示主頁,我將使用石灰的品牌顏色。 為了讓 Chakra UI 知道這種顏色,我將在我的項目目錄的根目錄中名為chakra的文件夾中創建一個customeTheme對象(你可以隨意調用它)。 在這個對像中,我將定義我們的品牌調色板。

在您創建的文件夾中創建一個名為theme.js的文件,然後添加以下代碼段:

 // ./chakra/theme.js const customTheme = { colors: { brand: { 50: '#f6fcee', 100: '#e2f4c8', 200: '#cbec9e', 300: '#b2e26e', 400: '#94d736', 500: '#75c800', 600: '#68b300', 700: '#599900', 800: '#477900', 900: '#294700' } } } module.exports = customTheme

現在讓我們將自定義主題合併到 Chakra UI。 我們在nuxt.config.js中這樣做。 首先,我們需要自定義主題對象:

 import customTheme from './chakra/theme'

接下來,我們必須指定 Chakra UI Nuxt 模塊提供的chakra密鑰,並將customTheme傳遞給extendTheme屬性:

 chakra: { extendTheme: customTheme },

您的nuxt.config.js文件應如下所示:

 // nuxt.config.js import customTheme from './chakra/theme' export default { mode: 'spa', /* * Headers of the page */ head: { title: process.env.npm_package_name || '', meta: [ { charset: 'utf-8' }, { name: 'viewport', content: 'width=device-width, initial-scale=1' }, { hid: 'description', name: 'description', content: process.env.npm_package_description || '' } ], link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }] }, /* * Customize the progress-bar color */ loading: { color: '#fff' }, /* * Global CSS */ css: [], /* * Plugins to load before mounting the App */ plugins: [], /* * Nuxt.js dev-modules */ buildModules: [ // Doc: https://github.com/nuxt-community/eslint-module '@nuxtjs/eslint-module' ], /* * Nuxt.js modules */ modules: [ '@chakra-ui/nuxt', '@nuxtjs/emotion' ], chakra: { extendTheme: customTheme }, /* * Build configuration */ build: { /* * You can extend webpack config here */ extend (config, ctx) {} } }

當您使用npm run dev運行應用程序時,您的主頁應該如下所示:

展示 Chakra UI 和 NuxtJS 的演示應用程序
(大預覽)

現在我們已經成功安裝了 Chakra UI 並添加了我們應用程序的自定義主題,讓我們開始構建 Chakra-ui 瀏覽器。

創建我們的主導航

我們希望我們的導航有我們的品牌名稱,在這種情況下,它將是Chakra-ui explorer 、2 個導航鏈接:文檔Repo ,以及一個負責切換顏色模式的按鈕。 讓我們在名為NavBarcomponents目錄下創建一個新組件,我們將在其中使用 Chakra UI 創建應用程序的主導航。

我們開工吧。 將以下代碼段添加到NavBar.vue

 <template> <c-box as="nav" h="60px" px="4" d="flex" align-items="center" shadow="sm" > <c-link as="nuxt-link" to="/" color="brand.700" font-weight="bold" :_hover="{ color: 'brand.900' }" > Chakra-ui Explorer </c-link> <c-box as="ul" color="gray.500" d="flex" align-items="center" list-style-type="none" ml="auto" > <c-box as="li" mr="8"> <c-link color="gray.500" :_hover="{ color: 'brand.400' }" is-external href="https://vue.chakra-ui.com" > Documentation </c-link> </c-box> <c-box as="li" mr="8"> <c-link color="gray.500" :_hover="{ color: 'brand.400' }" is-external href="https://github.com/chakra-ui/chakra-ui-vue" > Repo </c-link> </c-box> <c-box as="li"> <c-icon-button variant="ghost" variant-color="gray[900]" aria-label="Switch to dark mode" icon="moon" /> </c-box> </c-box> </c-box> </template> <script> import { CBox, CLink, CIconButton } from '@chakra-ui/vue' export default { name: 'NavBar', components: { CBox, CLink, CIconButton } } </script>

接下來,我們需要在我們的默認佈局組件default.vue中導入這個組件並將其添加到我們的模板中,因此我們的默認佈局總體上應該如下所示:

 <template> <div class="container"> <c-theme-provider> <c-color-mode-provider> <c-box as="section"> <c-reset /> <nav-bar /> <nuxt /> </c-box> </c-color-mode-provider> </c-theme-provider> </div> </template> <script> import { CThemeProvider, CColorModeProvider, CReset, CBox } from '@chakra-ui/vue' import NavBar from '@/components/NavBar' export default { name: 'DefaultLayout', components: { CThemeProvider, CColorModeProvider, CReset, CBox, NavBar } } </script>

當你現在運行你的應用程序時,你會看到:

您可以看到導航已經可以訪問,甚至無需指定它。 這只能在您按鍵盤上的Tab鍵時看到; Chakra UI 處理焦點管理,而您可以專注於導航菜單上的每個鏈接。

as道具

從上面的NavBar.vue片段中,您會注意到as屬性。 這是 Chakra UI 組件可用的功能,它允許您傳遞 HTML 標記或另一個組件以作為組件的基本標記連同其所有樣式和道具一起呈現。 所以當我們這樣做時:

 <c-box as="li"> <c-icon-button variant="ghost" variant-color="gray[900]" aria-label="Switch to dark mode" icon="moon" /> </c-box>

我們要求 Chakra UI 渲染一個<li>元素並在其中放置一個按鈕組件。 您還可以在此處看到我們使用該模式:

 <c-link as="nuxt-link" to="/" color="brand.700" font-weight="bold" :_hover="{ color : 'brand.900' }"> ChakraMart </c-link>

在上述情況下,我們要求 Chakra UI 渲染 Nuxt 的 <nuxt-link /> 組件。

as屬性使您能夠在標記的上下文中使用正確(或錯誤)元素。 這意味著,您可以利用它來使用語義標記構建您的應用程序模板,這將使您的應用程序對屏幕閱讀器更有意義。 因此,不用為應用程序的主要內容使用通用的div元素,而是使用as屬性渲染一個main元素,告訴屏幕閱讀器這是應用程序的主要內容。

注意查看 Chakra UI 組件公開的所有道具的文檔。 此外,請仔細查看chakra/theme.js中的品牌顏色是如何指定的。 您可以從上面的代碼片段中看到,我們將它用作 Chakra UI 提供的任何顏色。 要注意的另一件事是我們在導航欄上用於CIconButtonmoon圖標。 moon圖標是 Chakra UI 提供的默認圖標之一。

顏色模式

Chakra UI 的功能之一是顏色模式支持。 從 Chakra-ui 瀏覽器導航中moon圖標的使用可以看出,我們計劃集成暗模式。 因此,與其把它留到最後,讓我們把它結束並立即連接起來。 為此, CColorModeProvider使用 Vue 的提供/注入、提供、 $chakraColorMode$toggleColorMode函數。 $chakraColorMode返回應用程序的當前顏色模式,而$toggleColorMode將顏色模式從light切換到dark ,反之亦然。 要使用這兩個函數,我們需要將它們注入到NavBar.vue組件中。 讓我們在下面的<script />部分執行此操作:

 <script> <script> import { CBox, CLink, CIconButton } from '@chakra-ui/vue' export default { name: 'NavBar', inject: ['$chakraColorMode', '$toggleColorMode'], components: { CBox, CLink, CIconButton }, } </script>

讓我們創建一個計算屬性來返回顏色模式:

 ... computed: { colorMode () { return this.$chakraColorMode() } }

現在我們已經在NavBar.vue中註入了這兩個函數,讓我們修改切換顏色模式按鈕。 我們將從圖標開始,以便根據顏色模式顯示不同的圖標。 我們的CIconButton組件現在在這種狀態下看起來像這樣:

 <c-icon-button variant="ghost" variant-color="gray[900]" aria-label="Switch to dark mode" :icon="colorMode == 'light' ? 'moon' : 'sun'" />

目前,我們使用aria-label屬性來告訴屏幕閱讀器切換到暗模式。 讓我們修改它以支持明暗模式:

 <c-icon-button variant="ghost" variant-color="gray[900]" :aria-label="`Switch to ${colorMode == 'light' ? 'dark : 'light'} mode`" :icon="colorMode == 'light' ? 'moon' : 'sun'" />

最後,我們將在按鈕上添加一個單擊事件處理程序,以使用$toggleColorMode函數來切換應用程序的顏色模式。 像這樣:

 <c-icon-button variant="ghost" variant-color="gray[900]" :aria-label="`Switch to ${colorMode == 'light' ? 'dark' : 'light'} mode`" :icon="colorMode == 'light' ? 'moon' : 'sun'" @click="$toggleColorMode" />

為了測試我們的顏色模式設置是否有效,我將添加顏色模式的插值和CIconButton旁邊的文本來切換我們的顏色模式。 像這樣:

 <c-box as="li"> <c-icon-button variant="ghost" variant-color="gray[900]" :aria-label="`Switch to ${colorMode == 'light' ? 'dark' : 'light'} mode`" :icon="colorMode == 'light' ? 'moon' : 'sun'" @click="$toggleColorMode" /> Current mode: {{ colorMode }} </c-box>

這是我們的應用程序當前的樣子:

所以我們已經完成了在 Chakra UI 中設置顏色模式的繁重工作。 所以現在我們可以根據顏色模式為我們的應用程序設置樣式。 讓我們去default.vue並使用CColorModeProvider提供的顏色模式插槽屬性來設置我們的應用程序的樣式。 讓我們先在default.vue中修改我們的模板。

 <template> <div class="container"> <c-theme-provider> <c-color-mode-provider #default="{ colorMode }"> <c-box v-bind="mainStyles[colorMode]" w="100vw" h="100vh" as="section" > <c-reset /> <nav-bar /> <nuxt /> </c-box> </c-color-mode-provider> </c-theme-provider> </div> </template>

我們從 CColorModeProvider 提供的 slot props 屬性中CColorModeProvider colorMode然後將其作為動態鍵傳遞給我們稍後將創建的mainStyle對象。 這個想法是根據colorMode值使用一組不同的樣式。 我還使用速記道具的寬度和高度 - wh分別設置我們的CBox組件的寬度和高度。 讓我們在腳本部分定義這個mainStyles對象:

 <script> import { CThemeProvider, CColorModeProvider, CReset, CBox } from '@chakra-ui/vue' import NavBar from '@/components/NavBar' export default { name: 'DefaultLayout', components: { CThemeProvider, CColorModeProvider, CReset, CBox, NavBar }, data () { return { mainStyles: { dark: { bg: 'gray.900', color: 'whiteAlpha.900' }, light: { bg: 'whiteAlpha.900', color: 'gray.900' } } } } } </script>

Chakra-ui 瀏覽器現在支持黑暗模式!

現在我們有了導航欄,並且成功地為我們的應用程序設置了暗模式支持,讓我們關注pages/目錄中的index.vue ,在那裡可以找到我們應用程序的核心。 我們將從添加一個CBox組件開始,如下所示:

 <c-box as="main" d="flex" direction="column" align-items="center" p="10" > </c-box>

然後我們將在其中添加CInput組件。 我們的index.vue頁面組件將如下所示:

 <template> <c-box as="main" d="flex" align-items="center" direction="column" w="auto" p="16" > <c-input placeholder="Search components..." size="lg" mb="5" is-full-width /> </c-box> </template> <script> import { CBox, CInput } from '@chakra-ui/vue' export default { components: { CBox, CInput } } </script>

這是我們的應用程序現在的樣子:

您可以從上面的截屏視頻中看到CInput元素如何自動知道它何時處於黑暗模式並進行相應調整,即使我們沒有明確設置它也是如此。 此外,用戶可以點擊 tab 鍵來關注該CInput組件。

添加組件列表

因此,Chakra-ui 瀏覽器的想法(如前所述)是向用戶展示 Chakra UI 中所有可用的組件,以便我們可以擁有這些組件的列表以及將用戶帶到文檔的鏈接的組件。 為此,我將在項目目錄的根目錄下創建一個名為data的文件夾,然後創建一個名為index.js的文件。 在index.js中,我將導出一個包含組件名稱的對像數組。 以下是文件的外觀:

 // ./data/index.js export const components = [ { name: 'Accordion' }, { name: 'Alert' }, { name: 'AlertDialog' }, { name: 'AspectRatioBox' }, { name: 'AspectRatioBox' }, { name: 'Avatar' }, { name: 'Badge' }, { name: 'Box' }, { name: 'Breadcrumb' }, { name: 'Button' }, { name: 'Checkbox' }, { name: 'CircularProgress' }, { name: 'CloseButton' }, { name: 'Code' }, { name: 'Collapse' }, { name: 'ControlBox' }, { name: 'Divider' }, { name: 'Drawer' }, { name: 'Editable' }, { name: 'Flex' }, { name: 'Grid' }, { name: 'Heading' }, { name: 'Icon' }, { name: 'IconButton' }, { name: 'IconButton' }, { name: 'Input' }, { name: 'Link' }, { name: 'List' }, { name: 'Menu' }, { name: 'Modal' }, { name: 'NumberInput' }, { name: 'Popover' }, { name: 'Progress' }, { name: 'PseudoBox' }, { name: 'Radio' }, { name: 'SimpleGrid' }, { name: 'Select' }, { name: 'Slider' }, { name: 'Spinner' }, { name: 'Stat' }, { name: 'Stack' }, { name: 'Switch' }, { name: 'Tabs' }, { name: 'Tag' }, { name: 'Text' }, { name: 'Textarea' }, { name: 'Toast' }, { name: 'Tooltip' } ]

為了完成我們的實現,我將把上面的數組導入pages/index.vue並對其進行迭代以顯示所有組件。 此外,我們將讓用戶能夠使用搜索框過濾組件。 這是完整的實現:

 // pages/index.vue <template> <c-box as="main" d="flex" align-items="space-between" flex-direction="column" w="auto" p="16" > <c-input v-model="search" placeholder="Search components..." size="lg" mb="10" is-full-width /> <c-grid template-columns="repeat(4, 1fr)" gap="3" p="5"> <c-box v-for="(chakraComponent, index) of filteredComponents" :key="index" h="10"> {{ chakraComponent.name }} <c-badge> <c-link is-external :href="lowercase(`https://vue.chakra-ui.com/${chakraComponent.name}`)" > <c-icon name="info" size="18px" /> </c-link> </c-badge> </c-box> </c-grid> </c-box> </template> <script> import { CBox, CInput, CGrid, CLink, CBadge, CIcon } from '@chakra-ui/vue' import { components as chakraComponents } from '../data' export default { components: { CBox, CInput, CGrid, CBadge, CIcon, CLink }, data () { return { search: '' } }, computed: { filteredComponents () { return chakraComponents.filter((component) => { return this.lowercase(component.name).includes(this.lowercase(this.search)) }) } }, methods: { lowercase (value) { return value.toLowerCase() } } } </script>

現在我們的應用程序看起來像這樣:

您現在可以看到組件列表的暗模式是如何自動進行的,以及如何為鏈接添加焦點管理(默認情況下)以幫助可訪問性。

測試脈輪 UI

最後,讓我們通過在其上運行 Lighthouse 可訪問性測試來看看我們的應用程序的得分情況。 請注意,此測試基於 Axe 用戶影響評估。 以下是測試的截屏視頻。 您也可以按照以下步驟自行運行測試。

從上面的截屏視頻中,您可以看到我們的 Chakra UI 應用在燈塔可訪問性測試中的得分為85

結論

在本文中,我們談到了構建可訪問界面的需求,並且我們還通過為 Chakra UI 組件構建了一個資源管理器(Chakra-ui explorer),了解瞭如何使用 Chakra UI 從頭開始構建可訪問的應用程序。

  • 查看 Netlify 上的實時應用程序 →
  • 鏈接到回購 →