@@ -8,6 +8,7 @@ import type { Attributes } from '@utils/helpers';
88import { inheritAriaAttributes , assert , clamp , isEndSide as isEnd } from '@utils/helpers' ;
99import { menuController } from '@utils/menu-controller' ;
1010import { BACKDROP , GESTURE , getPresentedOverlay } from '@utils/overlays' ;
11+ import { isPlatform } from '@utils/platform' ;
1112import { hostContext } from '@utils/theme' ;
1213
1314import { config } from '../../global/config' ;
@@ -631,8 +632,22 @@ export class Menu implements ComponentInterface, MenuI {
631632 private beforeAnimation ( shouldOpen : boolean , role ?: string ) {
632633 assert ( ! this . isAnimating , '_before() should not be called while animating' ) ;
633634
634- // add aria-hidden to the menu
635- this . el . setAttribute ( 'aria-hidden' , 'true' ) ;
635+ /**
636+ * When the menu is presented on an Android device, TalkBack's focus rings
637+ * may appear in the wrong position due to the transition (specifically
638+ * `transform` styles). This occurs because the focus rings are initially
639+ * displayed at the starting position of the elements before the transition
640+ * begins. This workaround ensures the focus rings do not appear in the
641+ * incorrect location.
642+ *
643+ * If this solution is applied to iOS devices, then it leads to a bug where
644+ * the overlays cannot be accessed by screen readers. This is due to
645+ * VoiceOver not being able to update the accessibility tree when the
646+ * `aria-hidden` is removed.
647+ */
648+ if ( isPlatform ( 'android' ) ) {
649+ this . el . setAttribute ( 'aria-hidden' , 'true' ) ;
650+ }
636651
637652 // this places the menu into the correct location before it animates in
638653 // this css class doesn't actually kick off any animations
@@ -690,12 +705,18 @@ export class Menu implements ComponentInterface, MenuI {
690705 }
691706
692707 if ( isOpen ) {
708+ /**
709+ * When the menu is presented on an Android device, TalkBack's focus rings
710+ * may appear in the wrong position due to the transition (specifically
711+ * `transform` styles). The menu is hidden from screen readers during the
712+ * transition to prevent this. Once the transition is complete, the menu
713+ * is shown again.
714+ */
715+ this . el . removeAttribute ( 'aria-hidden' ) ;
716+
693717 // emit open event
694718 this . ionDidOpen . emit ( ) ;
695719
696- // remove aria-hidden from menu
697- this . el . removeAttribute ( 'aria-hidden' ) ;
698-
699720 /**
700721 * Move focus to the menu to prepare focus trapping, as long as
701722 * it isn't already focused. Use the host element instead of the
0 commit comments