Upgrade to Pro — share decks privately, control downloads, hide ads and more …

アクセシビリティ、まだ完璧じゃないけど ── “今から”できること

Avatar for Kuno Ayana Kuno Ayana
November 13, 2025
36

アクセシビリティ、まだ完璧じゃないけど ── “今から”できること

FlutterKaigi 2025

Avatar for Kuno Ayana

Kuno Ayana

November 13, 2025
Tweet

Transcript

  1. "DDFTJCJMJUZGPSFWFSZPOF w ੈքਓޱͷҎ্ʢਓʹਓʣ͕ԿΒ͔ͷো͕͍Λ๊͑ͯੜ׆͍ͯ͠Δ<> w ো͕͍͸୭Ͱ΋Ұ࣌తɾঢ়گతʹى͜Γ͏Δ w ยखͰΞϓϦΛ࢖༻͍ͯ͠Δਓ΍໌Δ͍೔ޫԼͰ࢖༻͢Δ৔߹ͳͲ w :PVNJHIUBMTPUIJOLPGBDDFTTJCJMJUZBTUSFBUJOHFWFSZPOFUIFTBNF BOE

    HJWJOHUIFNFRVBMPQQPSUVOJUJFT OPNBUUFSXIBUUIFJSBCJMJUZPS DJSDVNTUBODFT<>  <>IUUQTXXXXIPJOUOFXTSPPNGBDUTIFFUTEFUBJMEJTBCJMJUZBOEIFBMUI ΞΫηε <>IUUQTEFWFMPQFSNP[JMMBPSHFO64EPDT-FBSO@XFC@EFWFMPQNFOU$PSF"DDFTTJCJMJUZ8IBU@JT@BDDFTTJCJMJUZ ΞΫηε ΞΫηγϏϦςΟͱ͍͏ͷ͸ো͕͍ͷ༗ແ΍ೳྗʹؔΘΒͣ ʰ୭ʹͱͬͯ΋࢖͍΍͍͢ʱΑ͏ʹ͢Δ͜ͱ
  2. ࠃࡍతͳج४8$"(  w 8$"(ʢ8FC$POUFOU"DDFTTJCJMJUZ(VJEFMJOFTʣ<> w ੈքతʹ࢖ΘΕ͍ͯΔ΢Σϒ΍ΞϓϦͷΞΫηγϏϦςΟج४ w ࠷৽൛ɿ8$"(ʢ೥݄ʣ w ओͳݪଇ

    w ஌֮Մೳ 1FSDFJWBCMF rࢹ֮ɾௌ֮ͷ੍ݶʹؔΘΒͣ஌֮Ͱ͖Δ w ૢ࡞Մೳ 0QFSBCMF rͲΜͳೖྗํ๏Ͱ΋ૢ࡞Ͱ͖Δ w ཧղՄೳ 6OEFSTUBOEBCMF r௚ײతͰཧղ͠΍͍͢ w ݎ࿚ 3PCVTU rͲΜͳ؀ڥʢ֎Ε஋͕ೖͬͨΓΞϓσͨ͠ΓʣͰ΋յΕʹ͍͘ <>IUUQTXBJDKQUSBOTMBUJPOT8$"(BCTUSBDU ΞΫηε
  3. 'MVUUFS"DDFTTJCJMJUZSFMFBTFDIFDLMJTU <>   4DSFFOSFBEFSUFTUJOH w ϖʔδ্ͷ͢΂ͯͷίϯτϩʔϧ͸આ໌͞ΕΔ΂͖ w 5BML#BDL "OESPJE

    ͱ7PJDF0WFS J04 Λ࢖ͬͯΞϓϦΛςετ͢Δ <>IUUQTEPDT fl VUUFSEFWVJBDDFTTJCJMJUZBDDFTTJCJMJUZSFMFBTFDIFDLMJTU ΞΫηε εΫϦʔϯϦʔμʔͰͷ εϥΠμʔͷ࢖͍ํΛ ಡΈ্͛ͯڭ͑ͯ͘ΕΔ Ϙλϯ͸ʰϘλϯʱͱಡΈ্͛ΒΕΔ
  4. খωλɿεΫϦʔϯϦʔμʔͷىಈํ๏  w 7PJDF0WFSʢJ04J1IPOF1SPʹͯ֬ೝʣ w ઃఆը໘ΞΫηγϏϦςΟ7PJDF0WFSΛΦϯ w 4JSJʹʰ7PJDF0WFSΛΦϯʹͯ͠ʱͱཔΉ w 5BML#BDLʢ"OESPJE(BMBYZ;'MJQʹͯ֬ೝʣ

     w ઃఆը໘Ϣʔβิॿ5BML#BDLΛΦϯ γϣʔτΧοτΛ௥Ճ͓ͯ͘͠ͱ ӈԼͷϘλϯΛԡ͚ͩ͢Ͱىಈ ίϯτϩʔϧηϯλʔʹ௥Ճ͓ͯ͘͠ͱ ϘλϯΛԡ͚ͩ͢Ͱىಈ
  5. 'MVUUFS"DDFTTJCJMJUZSFMFBTFDIFDLMJTU <>   $POUSBTUSBUJPT w ςΩετͱഎܠͷίϯτϥετൺ͸গͳ͘ͱ΋ʹ͢Δ͜ͱΛਪ঑ w ແޮԽ͞ΕͨίϯϙʔωϯτΛআ͘ w

    ίϯτϥετνΣοΧʔαΠτͳͲ<> Ͱ֬ೝ͢Δͱྑ͍ <>IUUQTEPDT fl VUUFSEFWVJBDDFTTJCJMJUZBDDFTTJCJMJUZSFMFBTFDIFDLMJTU ΞΫηε <>IUUQTXFCBJNPSHSFTPVSDFTDPOUSBTUDIFDLFS ΞΫηε 0, /( ʢബͯ͘ಡΈͮΒ͍ʣ
  6. 'MVUUFS"DDFTTJCJMJUZSFMFBTFDIFDLMJTU <>   5BQQBCMFUBSHFUT w λοϓՄೳͳλʔήοτ͸͢΂ͯগͳ͘ͱ΋YQYͰ͋Δඞཁ͕͋Δ w J04)*(ͩͱYQY<> w

    े෼ͳύσΟϯάΛઃ͚Δ͜ͱ΋ॏཁ w "OESPJE.BUFSJBM%FTJHO . ͩͱYEQ<> <>IUUQTEPDT fl VUUFSEFWVJBDDFTTJCJMJUZBDDFTTJCJMJUZSFMFBTFDIFDLMJTU ΞΫηε <>IUUQTEFWFMPQFSBQQMFDPNEFTJHOIVNBOJOUFSGBDFHVJEFMJOFTBDDFTTJCJMJUZ ΞΫηε <>IUUQTNNBUFSJBMJPDPNQPOFOUTJDPOCVUUPOTBDDFTTJCJMJUZ ΞΫηε
  7. 'MVUUFS"DDFTTJCJMJUZSFMFBTFDIFDLMJTU <>   $PMPSWJTJPOEF fi DJFODZUFTUJOH w ৭֮ҟৗϞʔυ͓ΑͼάϨʔεέʔϧϞʔυͰ࢖༻Մೳ͔ͭ൑ಡՄೳ άϥϑͷ۠ผ͕͖ͭ΍͍͢޻෉

    ˞࢖༻͍ͯ͠Δͷ͸EBSUNBUIύοέʔδͷΈ <>IUUQTEPDT fl VUUFSEFWVJBDDFTTJCJMJUZBDDFTTJCJMJUZSFMFBTFDIFDLMJTU ΞΫηε
  8. /FX"DDFTTJCJMJUZ'FBUVSFTJO'MVUUFS  <>    4FNBOUJDT5SFFͷίϯύΠϧΛ࠷దԽ w Ϗϧυ଎౓͕໿޲্ 

    4FNBOUJDT3PMF"1*ͷ௥Ճ w ΢ΟδΣοτʹࡉ͔͍ηϚϯςΟοΫϩʔϧΛׂΓ౰ͯՄೳʹ  εΫϦʔϯϦʔμʔ͕ΑΓଟ͘ͷίϯςΩετΛఏڙͰ͖ΔΑ͏ʹ w ྫɿνΣοΫϘοΫεͷঢ়ଶ͕ʮΦϯʯ͔ʮΦϑʯ͔Λೝࣝͯ͠ಡΈ্͛ <>IUUQTEDNEFWCMPHBDDFTTJCJMJUZ fl VUUFSQSBDUJDBMUJQTUPPMTDPEFZPVMMBDUVBMMZVTF ΞΫηε "3*"SPMFʹϚοϐϯά͞ΕΔ ˞8FCͷΈ
  9. /FX"DDFTTJCJMJUZ'FBUVSFTJO'MVUUFS  <>    ΢ΣϒͰͷϑΥʔΧεφϏήʔγϣϯ͕ΑΓεϜʔζʹ w ಥવͷδϟϯϓͳͲͷόάΛճආ 

    ϦϯΫΞΫηγϏϦςΟͱ5BML#BDL w ϦϯΫͱͯ͠ೝࣝ͠ʮμϒϧλοϓͯ͠ىಈʯͳͲͷώϯτΛදࣔ  8JOEPXTͷϋΠίϯτϥετϞʔυΛαϙʔτ  J04ͷԻ੠ίϯτϩʔϧͷվળ w ૢ࡞Ͱ͖ͳ͍΢ΟδΣοτʹ൪߸͕͔ͭͳ͍Α͏ʹ <>IUUQTEDNEFWCMPHBDDFTTJCJMJUZ fl VUUFSQSBDUJDBMUJQTUPPMTDPEFZPVMMBDUVBMMZVTF ΞΫηε ˞8FCͷΈ ˞7PJDF0WFSͱ͸ผ
  10. 4FNBOUJDTʹʮҙຯʯΛ఻͑Δ࢓૊Έ  w 4FNBOUJDT͕͋Δ͜ͱͰਓ͸ը໘্ͷߏ଄΍໨తΛཧղͰ͖Δ w ࠓͲͷը໘ɾঢ়ଶʹ͍Δͷ͔ʁ w Ͳ͜Λԡͤ͹࣍ͷϖʔδʹਐΊΔͷ͔ʁ w ॏཁͳ৘ใ͕Ͳ͜ʹ͋Δʁ

    w ͜ͷϘλϯ͸ԿͷͨΊʹ͋Δͷ͔ʁ w 'MVUUFSͰ͸֤8JEHFUʹରͯ͠ʮҙຯʯΛઃఆ͢Δ͜ͱ͕Ͱ͖Δ w ʮҙຯʯΛݩʹεΫϦʔϯϦʔμʔ͕Ի੠Ͱ಺༰΍໾ׂΛ఻͑Δ͜ͱ͕Ͱ͖Δ ࢹ֮ʹཔΒͳ͍Ϣʔβʔ΋ ֤෦෼ͷ໾ׂΛԻ੠Ͱཧղ͠ૢ࡞Ͱ͖Δ
  11. 4FNBOUJDT8JEHFU <>  w ೚ҙͷ8JEHFUʹ4FNBOUJDTΛ௥Ճ͢Δ͜ͱ͕Ͱ͖Δ <>IUUQTBQJ fl VUUFSEFW fl VUUFSXJEHFUT4FNBOUJDTDMBTTIUNM

    ΞΫηε 4FNBOUJDT8JEHFUͰ Ϙλϯͱ͍͏ҙຯΛ෇༩ ʮ͜Ε͸ϦϯΫͰ͋Δʯ ʮ͜Ε͸ςΩετϑΟʔϧυͰ͋Δʯ
  12. 4FNBOUJDT8JEHFU <>  w ೚ҙͷ8JEHFUʹ4FNBOUJDTΛ௥Ճ͢Δ͜ͱ͕Ͱ͖Δ w CPPMҎ֎ͷ߲໨΋͋Δ <>IUUQTBQJ fl VUUFSEFW

    fl VUUFSXJEHFUT4FNBOUJDTDMBTTIUNM ΞΫηε 4FNBOUJDT8JEHFUͰ Ϙλϯͱ͍͏ҙຯΛ෇༩ ಡΈ্͛จݴΛࢦఆͰ͖Δ ͲΜͳΞΫγϣϯͨ͠ΒԿ͕ى͜Δ͔Λ ఻͑Δ͜ͱ͕Ͱ͖Δ ʮ͜Ε͸ϦϯΫͰ͋Δʯ ʮ͜Ε͸ςΩετϑΟʔϧυͰ͋Δʯ
  13. 4FNBOUJDT8JEHFU <>  w 'MVUUFSඪ४8JEHFUʹ͸جຊతʹ4FNBOUJDT8JEHFU͕಺෦Ͱ࢖ΘΕ͍ͯΔ w ྫɿ*DPO#VUUPO<> <>IUUQTBQJ fl VUUFSEFW

    fl VUUFSXJEHFUT4FNBOUJDTDMBTTIUNM ΞΫηε <>IUUQTHJUIVCDPN fl VUUFS fl VUUFSCMPCNBTUFSQBDLBHFT fl VUUFSMJCTSDNBUFSJBMJDPO@CVUUPOEBSU- ΞΫηε class IconButton extends StatelessWidget { … @override Widget build(BuildContext context) { … return Semantics(button: true, enabled: onPressed != null, child: result); } 4FNBOUJDT8JEHFUͰ Ϙλϯͱ͍͏ҙຯΛ෇༩
  14. 4FNBOUJDT5SFF  w 4FNBOUJDT8JEHFUͰ8JEHFU͝ͱʹʮҙຯʯΛ࣋ͨͤͨ w 4FNBOUJDT5SFFͰʮҙຯͷߏ଄ʯΛ࡞Δ w 8JEHFUͱͯ͠͸ෳ਺͚ͩͲҙຯతʹ͸ͭͷ৔߹ͳͲ͕͋Δ w ͦͷͨΊ8JEHFU5SFFͱ͸Ұக͠ͳ͍

    ˞͜ͷ4FNBOUJDT5SFFΛߏஙͯ͠ҡ࣋͢Δॲཧ͕'MVUUFSͰ࠷దԽ ElevatedButton.icon( onPressed: () {}, icon: const Icon(Icons.send), label: const Text('ૹ৴'), ), 8JEHFUͱͯ͠͸ *DPOͱ5FYUͷͭ ಡΈ্͛͸ͭ ʮૹ৴Ϙλϯʯ
  15. (FTUVSF%FUFDUPSͰϘλϯΛ࡞Δͱʜ  GestureDetector( onTap: () { setState(() { _message =

    '͍͍Ͷ͕λοϓ͞Ε·ͨ͠ʂ'; }); }, child: Container( … child: Text( '͍͍Ͷ', ), ), ),
  16. (FTUVSF%FUFDUPSͰϘλϯΛ࡞Δͱʜ  GestureDetector( onTap: () { setState(() { _message =

    '͍͍Ͷ͕λοϓ͞Ε·ͨ͠ʂ'; }); }, child: Container( … child: Text( '͍͍Ͷ', ), ), ), (FTUVSF%FUFDUPS͸ σϑΥϧτͰ͸Ϙλϯѻ͍ʹͳΒͳ͍ͨΊ ʰʓʓϘλϯʱͱಡΈ্͛ΒΕͳ͍
  17. (FTUVSF%FUFDUPSͰϘλϯΛ࡞Δͱʜ  GestureDetector( onTap: () { setState(() { _message =

    '͍͍Ͷ͕λοϓ͞Ε·ͨ͠ʂ'; }); }, child: Container( … child: Text( '͍͍Ͷ', ), ), ), ͞Βʹʜ
  18. ࿈ଧ๷ࢭࡦΛ-JTOUFSͰ࣮૷  Listener( onPointerDown: (event) { // ΠϕϯτIDΛνΣοΫͯ͠ɼଞͷΠϕϯτ͕ॲཧதͰͳ͚Ε͹ड͚ೖΕΔ if (_focusedEventId

    != null) { _available = _focusedEventId == event.pointer; } else { _focusedEventId = event.pointer; _available = true; } }, child: GestureDetector( onTap: () { // available νΣοΫͱ 300ms σό΢ϯενΣοΫ if (_available) { final now = DateTime.now(); if (_lastTapTime == null || now.difference(_lastTapTime!) > const Duration(milliseconds: 300)) { _lastTapTime = now; setState(() { _message = '͍͍Ͷ͕λοϓ͞Ε·ͨ͠ʂ';
  19. ࿈ଧ๷ࢭࡦΛ-JTOUFSͰ࣮૷  Listener( onPointerDown: (event) { // ΠϕϯτIDΛνΣοΫͯ͠ɼଞͷΠϕϯτ͕ॲཧதͰͳ͚Ε͹ड͚ೖΕΔ if (_focusedEventId

    != null) { _available = _focusedEventId == event.pointer; } else { _focusedEventId = event.pointer; _available = true; } }, child: GestureDetector( onTap: () { // available νΣοΫͱ 300ms σό΢ϯενΣοΫ if (_available) { final now = DateTime.now(); if (_lastTapTime == null || now.difference(_lastTapTime!) > const Duration(milliseconds: 300)) { _lastTapTime = now; setState(() { _message = '͍͍Ͷ͕λοϓ͞Ε·ͨ͠ʂ'; -JTOUFS΢ΟδΣοτ͸ੜͷϙΠϯλʔΠϕϯτΛर͏΋ͷͰ͋Γ εΫϦʔϯϦʔμʔܦ༝ͷԾ૝తͳλοϓ͸रΘͳ͍ ˞ճ໨ϩϯάλοϓͳͲͰඪ४δΣενϟʹ੾Γସ͑ͨΒಧ͘
  20. ࿈ଧ๷ࢭࡦΛ-JTOUFSͰ࣮૷  Listener( onPointerDown: (event) { // ΠϕϯτIDΛνΣοΫͯ͠ɼଞͷΠϕϯτ͕ॲཧதͰͳ͚Ε͹ड͚ೖΕΔ if (_focusedEventId

    != null) { _available = _focusedEventId == event.pointer; } else { _focusedEventId = event.pointer; _available = true; } }, child: GestureDetector( onTap: () { // available νΣοΫͱ 300ms σό΢ϯενΣοΫ if (_available) { final now = DateTime.now(); if (_lastTapTime == null || now.difference(_lastTapTime!) > const Duration(milliseconds: 300)) { _lastTapTime = now; setState(() { _message = '͍͍Ͷ͕λοϓ͞Ε·ͨ͠ʂ'; PO1POUFS%PXOʹདྷͳ͍ͷͰ @BWBJMBCMF͕ͣͬͱUSVFʹͳΒͳ͍
  21. ࿈ଧ๷ࢭࡦΛ-JTOUFSͰ࣮૷  Listener( onPointerDown: (event) { // ΠϕϯτIDΛνΣοΫͯ͠ɼଞͷΠϕϯτ͕ॲཧதͰͳ͚Ε͹ड͚ೖΕΔ if (_focusedEventId

    != null) { _available = _focusedEventId == event.pointer; } else { _focusedEventId = event.pointer; _available = true; } }, child: GestureDetector( onTap: () { // available νΣοΫͱ 300ms σό΢ϯενΣοΫ if (_available) { final now = DateTime.now(); if (_lastTapTime == null || now.difference(_lastTapTime!) > const Duration(milliseconds: 300)) { _lastTapTime = now; setState(() { _message = '͍͍Ͷ͕λοϓ͞Ε·ͨ͠ʂ'; PO5BQ͕ݺ͹Εͯ΋ Կ΋࣮ߦ͞Εͳ͍ʂ
  22. ࿈ଧ๷ࢭࡦΛ-JTOUFSͰ࣮૷  Listener( onPointerDown: (event) { // ΠϕϯτIDΛνΣοΫͯ͠ɼଞͷΠϕϯτ͕ॲཧதͰͳ͚Ε͹ड͚ೖΕΔ if (_focusedEventId

    != null) { _available = _focusedEventId == event.pointer; } else { _focusedEventId = event.pointer; _available = true; } }, child: GestureDetector( onTap: () { // available νΣοΫͱ 300ms σό΢ϯενΣοΫ if (_available) { final now = DateTime.now(); if (_lastTapTime == null || now.difference(_lastTapTime!) > const Duration(milliseconds: 300)) { _lastTapTime = now; setState(() { _message = '͍͍Ͷ͕λοϓ͞Ε·ͨ͠ʂ'; PO5BQ͕ݺ͹Εͯ΋ Կ΋࣮ߦ͞Εͳ͍ʂ εΫϦʔϯϦʔμʔͷجຊૢ࡞Ͱ Կ΋ಈ͔ͤͳ͘ͳ͍ͬͯͨʜ μ ϒ ϧ λ ο ϓ
  23. 

  24. ͳͥ͜ͷΑ͏ͳ໰୊͕ى͖ͯ͠·ͬͨͷ͔  w νʔϜʹεΫϦʔϯϦʔμʔͷ࢖༻Ϣʔβ͕͍ͳͯ͘ؾ෇͚ͳ͔ͬͨ w ޙճ͠ʹͳΓ΍͍͢ w ࢓༷ͷᐆດ͞ w ͲΜͳಡΈ্͛จ͕͍͍ͷʁͲ͜·Ͱ΍ͬͨΒ׬੒ʁ

    w ༏ઌ౓ͷݟ͑ʹ͘͞ w ࣗ෼͝ͱͱͯ͠ଊ͑ͮΒ͍ w εέδϡʔϧͷ౎߹ w 'MVUUFS͸ര଎ͰϓϩμΫτΛ࡞Γͨͯ͘࠾༻͍ͯ͠Δͱ͜Ζ͕ଟ͍
  25. 'MVUUFSط஌ͷ໰୊  w εΫϩʔϧͯ͠΋Ի͕໐Βͣϖʔδ਺ͷಡΈ্͕͛͞Εͳ͍<> w εΫϩʔϧ͍ͯ͠Δͱ్தͰϑΥʔΧε͕֎Ε"QQ#BS΁ඈΜͰ͠·͏<>  <>IUUQTHJUIVCDPN fl VUUFS

    fl VUUFSJTTVFT ΞΫηε <>IUUQTHJUIVCDPN fl VUUFS fl VUUFSJTTVFT ΞΫηε 4XJGUͰ࣮૷ εΫϩʔϧ͢ΔͱʮϐοϖʔδʯͱಡΈ্͛ 'MVUUFSͰ࣮૷
  26. 'MVUUFSط஌ͷ໰୊  w εΫϩʔϧͯ͠΋Ի͕໐Βͣϖʔδ਺ͷಡΈ্͕͛͞Εͳ͍<> w εΫϩʔϧ͍ͯ͠Δͱ్தͰϑΥʔΧε͕֎Ε"QQ#BS΁ඈΜͰ͠·͏<>  <>IUUQTHJUIVCDPN fl VUUFS

    fl VUUFSJTTVFT ΞΫηε <>IUUQTHJUIVCDPN fl VUUFS fl VUUFSJTTVFT ΞΫηε 4XJGUͰ࣮૷ εΫϩʔϧ͢ΔͱʮϐοϖʔδʯͱಡΈ্͛ 'MVUUFSͰ࣮૷ ίϯτϦϏϡʔτνϟϯεʂ
  27. ௥ه  w TIPX4FNBOUJDT%FCVHHFSΛ࢖ͬͯΈΔ<> w ΞΫηγϏϦςΟͷςετΛݟͯΈΔ<> w 4FNBOUJDT$MBTTΛਂ΅Δ<> w TPSU,FZɿಡΈ্͛ॱংΛιʔτͰ͖Δ

    w -JRVJE(MBTT<> w ࣮͸ͪΌΜͱΨΠυϥΠϯʹԊͬͯΔ <>IUUQTBCPEZNFEJVNDPNBDDFTTJCJMJUZJO fl VUUFSUJQTGPSBNPSFJODMVTJWFBQQFFE ΞΫηε <>IUUQTBQJ fl VUUFSEFW fl VUUFS fl VUUFS@UFTU"DDFTTJCJMJUZ(VJEFMJOFDMBTTIUNM ΞΫηε <>IUUQTBQJ fl VUUFSEFW fl VUUFSXJEHFUT4FNBOUJDTDMBTTIUNM ΞΫηε <>IUUQTEFWFMPQFSBQQMFDPNKQWJEFPTQMBZXXED ΞΫηε