Angular метка переключателя материала и VoiceOver / ScreenReader - PullRequest
0 голосов
/ 17 марта 2020

У меня есть Angular Материал мат-радио-группы. Когда я тестирую его с помощью VoiceOver от Apple, каждая метка радио читается как «[метка] и еще один элемент»

Например,

<mat-radio-button value="envelope">Envelope</mat-radio-button>

Читается громко, как «Конверт и еще один предмет», когда сосредоточены. Почему?

Вот весь набор:

<mat-radio-group aria-label="My Package Type" [(ngModel)]="myPackageType" class="radio-package-type mat-radio-small">
   <mat-radio-button value="box">Box</mat-radio-button>
   <mat-radio-button value="envelope">Envelope</mat-radio-button>
   <mat-radio-button value="irregular">Irregular</mat-radio-button>
</mat-radio-group>

Вот обработанный HTML, скопированный из инструментов разработчика:

<mat-radio-group
  _ngcontent-gkg-c241=""
  role="radiogroup"
  aria-label="My Package Type"
  class="mat-radio-group radio-package-type mat-radio-small ng-pristine ng-valid is-value ng-touched"
  ng-reflect-model="box"
  ><mat-radio-button
    _ngcontent-gkg-c241=""
    value="box"
    class="mat-radio-button mat-accent mat-radio-checked"
    ng-reflect-value="box"
    tabindex="-1"
    id="mat-radio-2"
    ><label class="mat-radio-label" for="mat-radio-2-input"
      ><div class="mat-radio-container">
        <div class="mat-radio-outer-circle"></div>
        <div class="mat-radio-inner-circle"></div>
        <input
          type="radio"
          class="mat-radio-input cdk-visually-hidden"
          id="mat-radio-2-input"
          tabindex="0"
          name="mat-radio-group-0"
          value="box"
        />
        <div
          mat-ripple=""
          class="mat-ripple mat-radio-ripple mat-focus-indicator"
          ng-reflect-trigger="[object HTMLLabelElement]"
          ng-reflect-disabled="false"
          ng-reflect-centered="true"
          ng-reflect-radius="20"
          ng-reflect-animation="[object Object]"
        >
          <div class="mat-ripple-element mat-radio-persistent-ripple"></div>
        </div>
      </div>
      <div class="mat-radio-label-content">
        <span style="display: none;">&nbsp;</span>Box
      </div></label
    ></mat-radio-button
  ><mat-radio-button
    _ngcontent-gkg-c241=""
    value="envelope"
    class="mat-radio-button mat-accent"
    ng-reflect-value="envelope"
    tabindex="-1"
    id="mat-radio-3"
    ><label class="mat-radio-label" for="mat-radio-3-input"
      ><div class="mat-radio-container">
        <div class="mat-radio-outer-circle"></div>
        <div class="mat-radio-inner-circle"></div>
        <input
          type="radio"
          class="mat-radio-input cdk-visually-hidden"
          id="mat-radio-3-input"
          tabindex="0"
          name="mat-radio-group-0"
          value="envelope"
        />
        <div
          mat-ripple=""
          class="mat-ripple mat-radio-ripple mat-focus-indicator"
          ng-reflect-trigger="[object HTMLLabelElement]"
          ng-reflect-disabled="false"
          ng-reflect-centered="true"
          ng-reflect-radius="20"
          ng-reflect-animation="[object Object]"
        >
          <div class="mat-ripple-element mat-radio-persistent-ripple"></div>
        </div>
      </div>
      <div class="mat-radio-label-content">
        <span style="display: none;">&nbsp;</span>Envelope
      </div></label
    ></mat-radio-button
  ><mat-radio-button
    _ngcontent-gkg-c241=""
    value="irregular"
    class="mat-radio-button mat-accent"
    ng-reflect-value="irregular"
    tabindex="-1"
    id="mat-radio-4"
    ><label class="mat-radio-label" for="mat-radio-4-input"
      ><div class="mat-radio-container">
        <div class="mat-radio-outer-circle"></div>
        <div class="mat-radio-inner-circle"></div>
        <input
          type="radio"
          class="mat-radio-input cdk-visually-hidden"
          id="mat-radio-4-input"
          tabindex="0"
          name="mat-radio-group-0"
          value="irregular"
        />
        <div
          mat-ripple=""
          class="mat-ripple mat-radio-ripple mat-focus-indicator"
          ng-reflect-trigger="[object HTMLLabelElement]"
          ng-reflect-disabled="false"
          ng-reflect-centered="true"
          ng-reflect-radius="20"
          ng-reflect-animation="[object Object]"
        >
          <div class="mat-ripple-element mat-radio-persistent-ripple"></div>
        </div>
      </div>
      <div class="mat-radio-label-content">
        <span style="display: none;">&nbsp;</span>Irregular
      </div></label
    ></mat-radio-button
  ></mat-radio-group
>

1 Ответ

0 голосов
/ 03 апреля 2020

У меня была похожая проблема (macOS 10.15.3, Safari 13.0.5 и 10.15.4, 13.1, я не могу воспроизвести в Ma c Chrome 80 или iOS 13.3.1 Safari) , Похоже, это происходит, когда <label> имеет дочерние элементы с display: block, особенно если есть сочетание дочерних элементов с и без display: block или сочетание TextNodes и элементов с display:block.

В вашем случае метка является неявной (входной элемент является дочерней по отношению к метке) и явной (метка содержит атрибут, ссылающийся на идентификатор входной информации). Хотя это ненужное дублирование (как добавление tagindex="0" к элементу <input>), это не связано с проблемой. Я воспроизвел проблему с неявными и только явными метками и входными данными. Кажется, для воспроизведения проблемы необходимы две вещи:

  1. <label> изменено на display:block
  2. <label> имеет по крайней мере один дочерний элемент display:block, но не все дети с display:block

Изменение элемента метки таким образом, что одно из этих двух требований не выполняется, кажется, исправляет это.

<!-- VoiceOver is saying "First Nameandone more item, edit text" -->
<!-- implicit -->
<label style="display:block"> 
    <span style="display:block">First Name</span>
    <input type="text"> 
</label>

<!-- explicit -->
<div>
    <label for="firstname3" class="block"> 
        First Name
        <span style="display:block">Test</span>
    </label>
    <input id="firstname3" type="text">
</div>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...