アクセシビリティ
SvelteKitは、デフォルトでアプリのアクセシブルなプラットフォームを提供するよう努めています。Svelteのコンパイル時のアクセシビリティチェックは、ビルドするSvelteKitアプリケーションにも適用されます。
SvelteKitの組み込みのアクセシビリティ機能がどのように機能し、これらの機能を最大限に活用するために何をする必要があるかについて説明します。SvelteKitはアクセシブルな基盤を提供していますが、アプリケーションコードがアクセス可能であることを確認するのはあなたの責任です。アクセシビリティを初めて使用する場合は、このガイドの「さらに読む」セクションで追加のリソースを参照してください。
アクセシビリティを正しく理解するのが難しい場合があることを認識しています。SvelteKitがアクセシビリティを処理する方法を改善する提案がある場合は、GitHub issueを開いてください。
ルートアナウンス
従来のサーバーレンダリングアプリケーションでは、すべてのナビゲーション(たとえば、<a>
タグをクリックするなど)によってページ全体がリロードされます。このとき、スクリーンリーダーやその他の支援技術は、新しいページのタイトルを読み上げて、ユーザーがページが変更されたことを理解できるようにします。
SvelteKitでのページ間のナビゲーションは、ページをリロードせずに(クライアントサイドルーティングとして知られています)発生するため、SvelteKitは、各ナビゲーション後に新しいページ名を読み上げるライブリージョンをページに挿入します。これにより、<title>
要素を調べてアナウンスするページ名が決定されます。
この動作のため、アプリ内のすべてのページには、一意で説明的なタイトルが必要です。SvelteKitでは、各ページに<svelte:head>
要素を配置することでこれを行うことができます。
<svelte:head>
<title>Todo List</title>
</svelte:head>
これにより、スクリーンリーダーやその他の支援技術がナビゲーションが発生した後に新しいページを識別できるようになります。説明的なタイトルを提供することは、SEOにも重要です。
フォーカス管理
従来のサーバーレンダリングアプリケーションでは、すべてのナビゲーションでフォーカスがページの先頭にリセットされます。これにより、キーボードまたはスクリーンリーダーでWebを閲覧する人が、最初からページを操作できるようになります。
クライアントサイドルーティング中にこの動作をシミュレートするために、SvelteKitは各ナビゲーション後、および拡張フォーム送信後に<body>
要素にフォーカスを合わせます。1つの例外があります。もし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
to_focus = var document: Document
document.ParentNode.querySelector<Element>(selectors: string): Element | null (+4 overloads)
Returns the first element that is a descendant of node that matches selectors.
querySelector('.focus-me');
const to_focus: Element | null
to_focus?.focus();
});
goto
関数を使用して、プログラムで別のページに移動することもできます。デフォルトでは、これはリンクをクリックするのと同じクライアントサイドルーティングの動作になります。ただし、goto
は、フォーカスをリセットするのではなく、現在フォーカスされている要素を保持するkeepFocus
オプションも受け入れます。このオプションを有効にする場合は、ナビゲーション後も現在フォーカスされている要素がページに存在することを確認してください。要素が存在しなくなった場合、ユーザーのフォーカスは失われ、支援技術ユーザーにとっては混乱を招く可能性があります。
“lang”属性
デフォルトでは、SvelteKitのページテンプレートはドキュメントのデフォルト言語を英語に設定します。コンテンツが英語でない場合は、src/app.html
の<html>
要素を更新して、正しいlang
属性を持たせる必要があります。これにより、ドキュメントを読み取る支援技術が正しい発音を使用できるようになります。たとえば、コンテンツがドイツ語の場合は、app.html
を次のように更新する必要があります。
<html lang="de">
コンテンツが複数の言語で利用可能な場合は、現在のページの言語に基づいてlang
属性を設定する必要があります。これは、SvelteKitのhandleフックを使用して行うことができます。
<html lang="%lang%">
/** @type {import('@sveltejs/kit').Handle} */
export function function handle({ event, resolve }: {
event: any;
resolve: any;
}): any
handle({ event: any
event, resolve: any
resolve }) {
return resolve: any
resolve(event: any
event, {
transformPageChunk: ({ html }: {
html: any;
}) => any
transformPageChunk: ({ html: any
html }) => html: any
html.replace('%lang%', function get_lang(event: any): string
get_lang(event: any
event))
});
}
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: Handle
handle: 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.
transformPageChunk: ({ html: string
html }) => html: string
html.String.replace(searchValue: string | RegExp, replaceValue: string): string (+3 overloads)
Replaces text in a string, using a regular expression or search string.
replace('%lang%', function get_lang(event: any): string
get_lang(event: RequestEvent<Partial<Record<string, string>>, string | null>
event))
});
};
さらに読む
ほとんどの場合、アクセス可能なSvelteKitアプリの構築は、アクセス可能なWebアプリの構築と同じです。次の一般的なアクセシビリティリソースからの情報を、構築するあらゆるWebエクスペリエンスに適用できるはずです。