View in English

  • メニューを開く メニューを閉じる
  • Apple Developer
検索
検索を終了
  • Apple Developer
  • ニュース
  • 見つける
  • デザイン
  • 開発
  • 配信
  • サポート
  • アカウント
次の内容に検索結果を絞り込む

クイックリンク

5 クイックリンク

ビデオ

メニューを開く メニューを閉じる
  • コレクション
  • トピック
  • すべてのビデオ
  • 利用方法

その他のビデオ

ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。

  • 概要
  • トランスクリプト
  • コード
  • Webアクセシビリティの最新情報

    カスタムコントロール、SSML、ダイアログ要素を使って、リッチでアクセシブルなWeb Appを構築するテクニックをご覧ください。さまざまな補助機能を解説しますので、Web Appのアクセシビリティをテストする際に役立てることができます。

    リソース

    • Dialog
    • Learn VoiceOver gestures on iPhone
    • Speech Synthesis Markup Language (SSML)
      • HDビデオ
      • SDビデオ

    関連ビデオ

    WWDC21

    • iOS Appにおけるフルキーボードアクセスのサポート
  • このビデオを検索

    こんにちは Tylerです WebKit Accessibility Teamのエンジニアです このセッションでは 最新の Webアクセシビリティ に関してお話します はじめに 読み上げ機能などの 補助機能についての 簡単な説明を行い

    次にWeb Speech APIと ダイアログ要素内で カスタムのコントロールや SSMLなどのツールを使って リッチでアクセッシブルな Web Appを作る方法を紹介します

    まずは補助機能についてです 世界中で7人に1人が 周囲やデバイス Webとの交流が困難な 障害を持っています 年齢やその期間に関わらず さまざまな症状を 患っているかもしれません Appleは最適な方法で デバイスを利用できる 数々のツールを 用意しています VoiceOverやスイッチコントロール そして音声コントロール フルキーボードアクセス など それぞれが異なる デバイスの利用方法を提供します これらのツールについては 昨年のセッション 「iOS Appにおけるフルキーボード アクセスのサポート」をご覧ください

    実際にVoiceOverを使い クイズサイトを ナビゲートしてみましょう iPadのトップボタンを3回 押しVoiceOverを有効にします Siri:VoiceOverオン Safari サイドバー表示 ボタン

    Tyler:VoiceOverがアクディブになり ページの冒頭をタップします Siri:ポップクイズ Heading レベル1 Tyler:右スワイプで ページ内を移動します Siri:6問中1つ目 8等分の ピザの4分の1は? 2スライス ラジオボタン 4つの1つ目 空白 3スライス 4スライス 6スライス 次の質問ボタン Tyler:Webデベロッパには VoiceOverのように ページをアクセシブルに する多くのツールがあります 例えばSafariには ボタンやh1からh6 table elementsや list elementsなどの セマンティック HTMLの サポートがあります セマンティック HTMLの使用を デフォルトにすれば ブラウザを通じて一貫した アクセシビリティ体験を ユーザーに提供できます しかしセマンティックHTMLでは 十分ではなく JavaScriptを使用しなければ ならない場合があります その場合 補助機能に セマンティックを 正しく伝えるため ARIA属性も 必要になるでしょう そこで2つ目のトピック カスタムのコントロールです 先ほどのピザのクイズを より使いやすいものにしたいとします ラジオボタンをカスタム コントロールに置き換え タップでピザをトレイから 動かせるようにします この場合のマークアップは divとidから始まります

    タップやクリックで これを可能にするには click event listenerが必要です id要素を受け入れる コンストラクタをもつ PizzaControl クラスを 作りましょう

    要素をIDで取得し click event listenerを追加します

    このlistenerがタップの 位置に基づきピザの数を計算し updateと呼ばれる関数に 値をパスしリレンダリングします しかし 誰もがこの機能を 使えるわけではありません

    例えばどこをタップすれば いいかわからない 目の不自由な ユーザーだったら? カスタムコンポーネントを 構築する際は さまざまなユーザーを 考慮する必要があります それを念頭に 最初のステップは 「slider」の値をもつrole属性 を与えることです 今回のコントロールには sliderがぴったりです 最小値は0スライス 最大値は8スライス 現在値は4スライスです キーボードなどタッチできない インターフェイス用に 0のtabindexを 追加します

    またARIA属性も必要です

    aria-valueminと aria-valuemaxは このsliderの最小・最大値を 伝達します

    これはrange type inputsの min max attributesに似ています

    次にaria-valuenowで 現在値を伝達します

    aria-valuetextで 分かりやすい説明を 追加します この場合「4スライス」です

    コントロールをフォーカス可能な スライダーとしたところで 補助機能から 受け取る値の処理が必要です iOSではVoiceOverが 指1本の上スワイプで スライダーの増加 そして下スワイプで スライダーの減少に 対応するようになっています これらのジェスチャーに Safariは簡単に対応できます VoiceOverのユーザーが スライダーを上スワイプすると Safariは右矢印キーと 同様にみなします 同じく下スワイプだと 左矢印キーと 同様にみなします これらは実際にキーを 押した時と同じように動作し key event listenersで 処理できます この知識とともに keydown listenerを コントロールに足しましょう 作動したキーが 右矢印か上矢印キーなら 現在値プラス1として コントロールを更新します 同様に作動したキーが 左矢印か下矢印キーなら 現在値マイナス1として コントロールを更新します これはVoiceOverを使う ユーザーだけでなく キーボードでWeb Appに アクセスするユーザーにも 応えることができます event listenersが 出来上がったところで 次は update 関数を 定義しましょう まず 与えられた範囲である 0から8に 値を制限し SliceCountの値を更新します 次にコントロールの ビジュアルおよびARIA表示を 更新します カスタムコンポーネントを 作成する際 ビジュアル表示を更新する時は ARIA表示も更新することを 覚えておきましょう

    この場合 aria-valuenowと aria-valuetextの属性を更新し コントロールの新しい値を ユーザーに知らせます

    まずaria-valuenowを 現在値に設定します

    次にaria-valuetextに わかりやすい説明 「スライスの数+枚」を 入れます 設定が終わったところで クイズのWeb Appに戻り VoiceOverを試してみましょう ピザをタップして フォーカスします Siri:4スライス 変更可能 指1本で上下にスワイプし 値を変更 Tyler:VoiceOverが スライダーの現在の値は 4スライスで 変更可能だと読み上げました その指示に従い上スワイプで スライス数を増やしていきます Siri:5スライス 6スライス Tyler:下スワイプで スライス数を減らします Siri:5スライス 4スライス Tyler:これらの変更によって カスタムスライダー コンポーネントが アクセシブルになりました 次にWeb Speech APIで SSMLを使い さらに豊かな体験を 提供してみましょう Web Speech APIは2つの JavaScriptからなります オーディオインプット用の SpeechRecognitionと オーディオアウトプット用の SpeechSynthesisです

    Web Speechは 音声補助機能付き または 音声のみのインターフェイスを Web Appに提供できます

    これは マウスやキーボード タッチスクリーンなどを 使用するのが困難な 運動機能に障がいのある方々に 便利です SafariのSpeechSynthesisの新機能として テキストの話し方を調整する SSMLを使用できるようになりました SSMLには多くの能力があります 例えばbreak要素を使って 任意のタイミングで スピーチにポーズを 加えることができます ユーザーに呼吸する指示を 出す時などに便利です

    phoneme要素を使って tomayto /tomahtoなどの 発音方法を指定できます

    prosody要素を使って 声のピッチや 速さ ボリュームを調節できます これらはSSMLの能力の ごく一部です SSMLの詳細は w3.orgをご覧ください ではSSMLを 実際に使ってみましょう 最後の問題は"the water"の スペイン語の正しい翻訳の ラジオボタンを選択してもらう クイズです ボタンを押して text-to-speechを使って 問題と解答を読み上げ SSMLでスペイン語のフレーズを 現地の言葉で 読み上げるようにすれば 非常に使いやすいものになります まずボタンを作成しますが この絵文字必要ないので span aria-hiddenを trueに指定し 絵文字を隠すことから 始めます

    次にwrapWithSSMLという JavaScriptのヘルパー関数で phraseとlocaleを指定します

    各フレーズ前にポーズを置くため break 要素でSSMLの ストリングを作成します

    prosody要素で デフォルト80%の速さで 読むよう指定します

    最後にlang要素で 現地の言葉で話すように 指定します

    さらに 「Read Question」ボタンに click event listenerを追加し その中にSSMLストリングを 作成します まずはストリングを speak要素ですべて囲みます

    speak要素は synthesis processorsに 中身がすべてSSMLだと 示すため重要です

    次にHow do you say "the water" in Spanish? という質問を含めます wrapWithSSMLヘルパー関数を使って 翻訳されるフレーズに強調を与え 米英語のローカル音声で 読むよう指定します

    4つの答えにも wrapWithSSMLを使い スペイン語のローカル音声で 読むよう指定します

    最後にSSMLで新しい SpeechSynthesisUtterance オブジェクトを作成し window.SpeechSynthesis. speakメソッドに渡して読み上げます

    では実際どう動作するか 見てみましょう 最後の問題ページで 「Read question」ボタンを押し 聞いてみます Siri:How do you say "the water" in Spanish? El agua La abuela La abeja El árbol Tyler:SSMLのおかげで 生徒にとって非常に 使いやすくなりました

    ウェブでよくあるデザインの もう一つがモーダルです

    サインインや登録フォーム 確認ダイアログなどに 使われています

    アクセシブルな モーダルを提供する方法の1つが aria-modal属性です aria-modalをtrueに するとSafariは モーダル外のアクセシブルな 要素を無視します 最近ではSafariでdialog要素が サポートされるようになりました dialog要素を使用すると アクセシブルな体験を これまで以上に簡単に提供できます 一般的なフォーカス操作に加え EscapeキーやiOSのスクラブのような 閉じるジェスチャーが 簡単になります それではこの例の 「Show score」ボタンを 結果のダイアログに 変更してみましょう

    まずdialog要素の作成が必要です マークアップはこのようになります show scoreボタンで後で参照できるよう dialogにIDを与えます ダイアログのコンテンツを dialogメソッドを含むformで囲みます

    これで 今回のボタンのような コントロールで ダイアログを 閉じることができます またモーダル開くのに JavaScriptが必要です dialog要素で showModal()を呼ぶ 「Show Score」ボタンに click event listenerを追加します

    では試してみましょう VoiceOverを稼働させ 「Show score」をタップします

    Siri:「Show score」ボタン

    Tyler:ボタンを押すには 指1本でダブルタップです Siri:スコアを表示 ダイアログ 「Close」ボタン Tyler: ここでモーダルが表示されます 左スワイプで スコアを聞くことができます Siri:全6問正解しました おめでとう! Tyler:右スワイプで 「Close」ボタンに 戻ります Siri:「Close」ボタン Tyler:ダブルタップで モーダルを閉じます Siri:チェックが外れました Tyler:先ほどお話したように iOSのスクラブのジェスチャーを ボックス外で行うことで dialog要素が モーダルを自動的に閉じてくれます ダブルタップで モーダルをまた開きます Siri:「Show score」ボタン Webダイアログ 「Close」ボタン Tyler:そして2本指で 右・左・右に 素早くスクラブします

    Siri:「Show score」ボタン Tyler:モーダルが出来上がりましたが さらに向上させることができます モーダルを開いた時 Webダイアログ 「Close」ボタン としか聞こえませんでした この場合 aria-labelまたは aria-labelledb属性で 追加の情報を 補助機能を用いて ユーザーに提供することができます モーダルの内容は短いので クイズの正解数を labelに使いましょう まずモーダルのコンテンツを span idで囲みます modal-content IDを指す dialogに aria-labelledby 属性を加えます

    またautofocus属性を 「Close」ボタンに加えることで モーダルの初期フォーカスを 明確にします

    これは今回のシンプルな モーダルでデフォルトでしたが モーダルにもっと コンテンツがあったり 複雑であれば 違ったかもしれません

    例えばコンテンツが多い モーダルの場合 top-level headingに autofocusを置くべきです モーダルを開発する皆さんに その判断を委ねます

    ではVoiceOverを 試してみましょう 「Show score」ボタンを タップしフォーカスします Siri:「Show score」ボタン

    Tyler:ダブルタップして押します Siri:全6問正解です おめでとう Webダイアログ 「Close」ボタン Tyler:よくなりましたね aria-labelledbyのおかげで すぐに得点を聞くことができて 「Close」ボタンに フォーカスしているので ダブルタップで モーダルを出られます ではこのセッションの まとめです すべてのユーザーに最高の体験を届ける リッチでアクセシブルな Web Appを作成する技術を 学ぶことができたかと思います これらをSafariでお試しになり バグがあれば WebKitのバグトラッカーで 報告してください 今日はご閲覧 ありがとうございました WWDCをお楽しみください

    • 3:06 - PizzaControl class with click event listener

      class PizzaControl {
        constructor(id) {
          this.control = document.getElementById(id);
          this.sliceCount = 4;
          
          this.control.addEventListener("click", (event) => {
            const newSliceCount = this.computeSliceCount(event);
            this.update(newSliceCount);
          });
        }
      }
    • 4:23 - PizzaControl HTML markup

      <div id="pizza-input" 
           role="slider" tabindex="0"
           aria-valuemin="0" aria-valuemax="8"
           aria-valuenow="4" aria-valuetext="4 slices">
      </div>
    • 5:15 - PizzaControl class with keydown event listener

      class PizzaControl {
        constructor(id) {
          this.control = document.getElementById(id);
          this.sliceCount = 4;
      
          // …click event listener…
          
          this.control.addEventListener("keydown", (event) => {
            const key = event.key;
            if (key === "ArrowRight" || key === "ArrowUp")
              this.update(this.sliceCount + 1);
            else if (key === "ArrowLeft" || key === "ArrowDown")
              this.update(this.sliceCount - 1);
          });
        }
      }
    • 5:41 - PizzaControl class update function

      class PizzaControl {
        // …constructor…
        
        update(newSliceCount) {
          this.sliceCount = Math.max(0, Math.min(newSliceCount, 8));
      
          // Visually re-render `this.sliceCount` slices
          // …
      
          // Update the ARIA representation of the control
          this.control.setAttribute("aria-valuenow", this.sliceCount);
          const sliceModifier = this.sliceCount === 1 ? "slice" : "slices";
          this.control.setAttribute("aria-valuetext", `${this.sliceCount} ${sliceModifier}`);
        }
      }
    • 7:52 - SSML examples

      <speak>
        Breathe in <break time="3s"/> and breathe out.
      </speak>
      
      <speak>
        <phoneme alphabet="ipa" ph="təˈmeɪtoʊ">tomato</phoneme>
        <phoneme alphabet="ipa" ph="təˈmɑːtəʊ">tomato</phoneme>
      </speak>
      
      <speak>
        <prosody pitch="-2st" rate="slow" volume="loud">
          Hello world!
        </prosody>
      </speak>
    • 8:45 - "Read question" button HTML markup

      <button id="read-question-btn">
        Read question<span aria-hidden="true">🔊</span>
      </button>
    • 8:57 - wrapWithSSML JavaScript function

      function wrapWithSSML(phrase, locale) {
        return `
          <break time=“100ms"/>
          <prosody rate=“80%">
            <lang xml:lang="${locale}">
              ${phrase}
            </lang>
          </prosody>
        `;
      }
    • 9:24 - Read question button click event listener

      const readQuestionButton =
        document.getElementById("read-question-btn");
      
      readQuestionButton.addEventListener("click", () => {
        const ssml = `
          <speak>
            How do you say
              ${wrapWithSSML("the water", "en-US")}
            in Spanish?
            ${wrapWithSSML("El agua", "es-MX")}
            ${wrapWithSSML("La abuela", "es-MX")}
            ${wrapWithSSML("La abeja", "es-MX")}
            ${wrapWithSSML("El árbol", "es-MX")}
          </speak>
        `;
        const utterance = new SpeechSynthesisUtterance(ssml);
        window.speechSynthesis.speak(utterance);
      });
    • 11:33 - Show score dialog HTML markup

      <dialog id="show-score-modal">
        <form method="dialog">
          You got all six questions correct. Great work!
          <button type="submit">Close</button>
        </form>
      </dialog>
    • 11:51 - JavaScript to open show score dialog

      const showScoreButton =
        document.getElementById("show-score-btn");
      
      showScoreButton.addEventListener("click", () => {
        document
          .getElementById("show-score-modal")
          .showModal();
      });
    • 13:23 - Show score dialog with autofocus and aria-labelledby attribute

      <dialog id="show-score-modal" aria-labelledby="modal-content">
        <form method="dialog">
          <span id="modal-content">
            You got all six questions correct. Great work!
          </span>
          <button type="submit" autofocus>Close</button>
        </form>
      </dialog>

Developer Footer

  • ビデオ
  • WWDC22
  • Webアクセシビリティの最新情報
  • メニューを開く メニューを閉じる
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    メニューを開く メニューを閉じる
    • アクセシビリティ
    • アクセサリ
    • App Extension
    • App Store
    • オーディオとビデオ(英語)
    • 拡張現実
    • デザイン
    • 配信
    • 教育
    • フォント(英語)
    • ゲーム
    • ヘルスケアとフィットネス
    • アプリ内課金
    • ローカリゼーション
    • マップと位置情報
    • 機械学習
    • オープンソース(英語)
    • セキュリティ
    • SafariとWeb(英語)
    メニューを開く メニューを閉じる
    • 英語ドキュメント(完全版)
    • 日本語ドキュメント(一部トピック)
    • チュートリアル
    • ダウンロード(英語)
    • フォーラム(英語)
    • ビデオ
    Open Menu Close Menu
    • サポートドキュメント
    • お問い合わせ
    • バグ報告
    • システム状況(英語)
    メニューを開く メニューを閉じる
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles(英語)
    • フィードバックアシスタント
    メニューを開く メニューを閉じる
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program(英語)
    • News Partner Program(英語)
    • Video Partner Program(英語)
    • セキュリティ報奨金プログラム(英語)
    • Security Research Device Program(英語)
    Open Menu Close Menu
    • Appleに相談
    • Apple Developer Center
    • App Store Awards(英語)
    • Apple Design Awards
    • Apple Developer Academy(英語)
    • WWDC
    Apple Developerアプリを入手する
    Copyright © 2025 Apple Inc. All rights reserved.
    利用規約 プライバシーポリシー 契約とガイドライン