跳至主要內容

無障礙功能

SvelteKit 致力於預設為您的應用程式提供一個無障礙的平台。Svelte 的編譯時無障礙檢查也將適用於您建立的任何 SvelteKit 應用程式。

以下是 SvelteKit 內建無障礙功能的工作方式,以及您需要做些什麼來幫助這些功能發揮最佳效果。請記住,雖然 SvelteKit 提供了無障礙的基礎,但您仍然有責任確保您的應用程式碼是無障礙的。如果您不熟悉無障礙功能,請參閱本指南的「進一步閱讀」部分以獲取其他資源。

我們認識到,要正確處理無障礙功能可能很困難。如果您想針對 SvelteKit 如何處理無障礙功能提出改進建議,請開啟一個 GitHub 問題

路由公告

在傳統的伺服器渲染應用程式中,每次導覽(例如點擊 <a> 標籤)都會觸發完整的頁面重新載入。當這種情況發生時,螢幕閱讀器和其他輔助技術會讀出新頁面的標題,以便使用者了解頁面已變更。

由於 SvelteKit 中頁面之間的導覽不會重新載入頁面(稱為用戶端路由),SvelteKit 會在頁面上注入一個即時區域,每次導覽後都會讀出新頁面的名稱。這會透過檢查 <title> 元素來決定要公告的頁面名稱。

由於這種行為,您應用程式中的每個頁面都應該有一個獨特且具有描述性的標題。在 SvelteKit 中,您可以透過在每個頁面上放置一個 <svelte:head> 元素來做到這一點

src/routes/+page
<svelte:head>
	<title>Todo List</title>
</svelte:head>

這將允許螢幕閱讀器和其他輔助技術在導覽發生後識別新頁面。提供描述性標題對於SEO也很重要。

焦點管理

在傳統的伺服器渲染應用程式中,每次導覽都會將焦點重置到頁面頂部。這可確保使用鍵盤或螢幕閱讀器瀏覽網路的人員將從頭開始與頁面互動。

為了在用戶端路由期間模擬此行為,SvelteKit 會在每次導覽和增強表單提交後將焦點置於 <body> 元素。有一個例外 - 如果存在具有 autofocus 屬性的元素,SvelteKit 會將焦點置於該元素。使用該屬性時,請務必考慮對輔助技術的影響

如果您想自訂 SvelteKit 的焦點管理,可以使用 afterNavigate 鉤子

import { function afterNavigate(callback: (navigation: import("@sveltejs/kit").AfterNavigate) => void): void

A lifecycle function that runs the supplied callback when the current component mounts, and also whenever we navigate to a new URL.

afterNavigate must be called during a component initialization. It remains active as long as the component is mounted.

afterNavigate
} from '$app/navigation';
function afterNavigate(callback: (navigation: import("@sveltejs/kit").AfterNavigate) => void): void

A lifecycle function that runs the supplied callback when the current component mounts, and also whenever we navigate to a new URL.

afterNavigate must be called during a component initialization. It remains active as long as the component is mounted.

afterNavigate
(() => {
/** @type {HTMLElement | null} */ const const to_focus: Element | null
@type{HTMLElement | null}
to_focus
= var document: Documentdocument.ParentNode.querySelector<Element>(selectors: string): Element | null (+4 overloads)

Returns the first element that is a descendant of node that matches selectors.

MDN Reference

querySelector
('.focus-me');
const to_focus: Element | null
@type{HTMLElement | null}
to_focus
?.focus();
});

您也可以使用 goto 函數以程式方式導覽至不同的頁面。預設情況下,這將具有與點擊連結相同的用戶端路由行為。但是,goto 也接受一個 keepFocus 選項,該選項將保留目前聚焦的元素,而不是重置焦點。如果您啟用此選項,請確保目前聚焦的元素在導覽後仍然存在於頁面上。如果元素不再存在,使用者的焦點將會遺失,這會對輔助技術使用者造成混亂的體驗。

“lang” 屬性

預設情況下,SvelteKit 的頁面範本會將文件的預設語言設定為英文。如果您的內容不是英文,您應該更新 src/app.html 中的 <html> 元素,使其具有正確的 lang 屬性。這將確保任何閱讀文件的輔助技術都使用正確的發音。例如,如果您的內容是德文,您應該將 app.html 更新為以下內容

src/app
<html lang="de">

如果您的內容有多種語言版本,您應該根據目前頁面的語言設定 lang 屬性。您可以使用 SvelteKit 的 handle 鉤子來做到這一點

src/app
<html lang="%lang%">
src/hooks.server
/** @type {import('@sveltejs/kit').Handle} */
export function 
function handle({ event, resolve }: {
    event: any;
    resolve: any;
}): any
@type{import('@sveltejs/kit').Handle}
handle
({ event: anyevent, resolve: anyresolve }) {
return resolve: anyresolve(event: anyevent, {
transformPageChunk: ({ html }: {
    html: any;
}) => any
transformPageChunk
: ({ html: anyhtml }) => html: anyhtml.replace('%lang%', function get_lang(event: any): string
@paramevent
get_lang
(event: anyevent))
}); }
import type { 
type Handle = (input: {
    event: RequestEvent;
    resolve(event: RequestEvent, opts?: ResolveOptions): MaybePromise<Response>;
}) => MaybePromise<...>

The handle hook runs every time the SvelteKit server receives a request and determines the response. It receives an event object representing the request and a function called resolve, which renders the route and generates a Response. This allows you to modify response headers or bodies, or bypass SvelteKit entirely (for implementing routes programmatically, for example).

Handle
} from '@sveltejs/kit';
export const const handle: Handlehandle:
type Handle = (input: {
    event: RequestEvent;
    resolve(event: RequestEvent, opts?: ResolveOptions): MaybePromise<Response>;
}) => MaybePromise<...>

The handle hook runs every time the SvelteKit server receives a request and determines the response. It receives an event object representing the request and a function called resolve, which renders the route and generates a Response. This allows you to modify response headers or bodies, or bypass SvelteKit entirely (for implementing routes programmatically, for example).

Handle
= ({ event: RequestEvent<Partial<Record<string, string>>, string | null>event, resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>resolve }) => {
return resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>resolve(event: RequestEvent<Partial<Record<string, string>>, string | null>event, {
ResolveOptions.transformPageChunk?(input: {
    html: string;
    done: boolean;
}): MaybePromise<string | undefined>

Applies custom transforms to HTML. If done is true, it’s the final chunk. Chunks are not guaranteed to be well-formed HTML (they could include an element’s opening tag but not its closing tag, for example) but they will always be split at sensible boundaries such as %sveltekit.head% or layout/page components.

@paraminput the html chunk and the info if this is the last chunk
transformPageChunk
: ({ html: stringhtml }) => html: stringhtml.String.replace(searchValue: string | RegExp, replaceValue: string): string (+3 overloads)

Replaces text in a string, using a regular expression or search string.

@paramsearchValue A string or regular expression to search for.
@paramreplaceValue A string containing the text to replace. When the {@linkcode searchValue} is a RegExp, all matches are replaced if the g flag is set (or only those matches at the beginning, if the y flag is also present). Otherwise, only the first match of {@linkcode searchValue} is replaced.
replace
('%lang%', function get_lang(event: any): string
@paramevent
get_lang
(event: RequestEvent<Partial<Record<string, string>>, string | null>event))
}); };

進一步閱讀

在大多數情況下,建立無障礙的 SvelteKit 應用程式與建立無障礙的網路應用程式相同。您應該能夠將以下一般無障礙資源中的資訊應用於您建立的任何網路體驗

在 GitHub 上編輯此頁面

上一頁 下一頁