Как я могу получить NVDA и подобное, чтобы зачитать aria-label И содержание ‹foreignobject›?

Это мой первый пост на StackOverflow, поэтому приношу свои извинения за любые ошибки. У меня есть графическое изображение дерева SVG, которое я хотел бы сделать доступным для пользователей NVDA и т.п. Каждый узел в графике SVG кодируется следующим образом:

<g class="node" >
<foreignObject tabindex="0" focusable="true" aria-label="I want this read by screen readers such as NVDA..." class="nodestyle">...and I'd like this read out as well.</foreignObject>
</g>

В тот момент, когда я перехожу к каждому узлу, Chrome просто считывает текст во внешнем объекте, а Edge Chromium считывает только текст aria-label в файле g. Я пробовал использовать title, label и т. Д. Как в g, так и в foreignobject, но не могу заставить ни один браузер прочитать оба фрагмента текста. Может ли кто-нибудь подсказать, как я могу этого добиться, если это вообще возможно? Я не хочу делать такие хакерские вещи, как вводить лишний текст, а затем скрывать его с помощью CSS. Спасибо


person Paddy UK    schedule 17.01.2020    source источник
comment
Чего вы пытаетесь достичь? то есть почему у узла, содержащего текст, есть дополнительная информация для программ чтения с экрана. Я спрашиваю, потому что может быть лучший способ структурировать ваш SVG. Да, и проверьте aria-labelledby, так как это позволит вам делать то, что вы хотите, с небольшой реструктуризацией. Я опубликую ответ, как только вы дадите мне вариант использования, который у вас есть, чтобы я мог проверить, что вы пытаетесь обойти проблему неверным способом (и в конечном итоге предлагаете плохой совет).   -  person Graham Ritchie    schedule 17.01.2020
comment
Спасибо за комментарий, @GrahamRitchie. Я сделал интерактивное дерево решений. Щелчок или нажатие Enter / Space на узлах открывает / закрывает дочерние ветви. Когда вкладка используется для навигации по узлам, фокус перемещается между узлами в разных ветвях. Для слепых пользователей я хочу, чтобы узлы читали что-то о родительском узле, чтобы они знали, где они находятся в дереве. В противном случае они могут перейти к узлу, сказав «Нет», без контекста того, на что они отвечают. Я мог переформулировать все вопросы, но моя брифинг требует минимальной многословности. Пример страницы: www.creativemedia.org.uk/interactive-trees/template.html   -  person Paddy UK    schedule 20.01.2020
comment
Привет, Пэдди, Великобритания, сбитый с толку добавленной вами ссылкой, возможно, это глупость, но я не могу найти дерево решений. Можете ли вы связать страницу, на которой оно находится, или указать мне точное место на странице.   -  person Graham Ritchie    schedule 20.01.2020
comment
Привет, @GrahamRitchie, извини, если я запутал. Код в ссылке - это то, о чем я спрашиваю, но в нем просто есть фиктивные данные. Возможно, я неправильно употребляю термин «дерево решений»; Я имею в виду разветвленную структуру вопросов / ответов, которые приводят пользователей к определенному выводу. Я обновил первый узел, и теперь это действительно вопрос.   -  person Paddy UK    schedule 20.01.2020


Ответы (2)


uk, я делал что-то очень похожее, хотя у меня нет поведения при открытии / закрытии, скрытии / отображении.

Это в значительной степени не решенная проблема, поэтому мне интересно узнать, какая работа проделана в этой области, и я надеюсь, что вы готовы к дальнейшей переписке! Обязательно ознакомьтесь с этой статьей. Я думаю, это часть любого правильного решения. Этот тоже заслуживает внимания.

Я пробовал много вещей, в том числе остановился на SVG с посторонним объектом и использовал табуляцию для навигации. Даже реализовано несколько разных механизмов выбора веток.

Сложность - это выбор веток. Есть атрибут aria-flowto, который принимает один или несколько идентификаторов «пункта назначения» в качестве значение, но у него очень плохая поддержка, и нет рекомендуемых идиом для выбора среди них. (Однако его можно заставить работать с javascript).

Одна из моих попыток использует javaScript для копирования содержимого ящиков на метку aria, прикрепленную к элементу с tabindex=0 на нем. Это работает довольно хорошо, но не дает никаких преимуществ «просматриваемого» контента. Опять же, объявление веток - это проблема.

Если вы хотите, чтобы разметка внутри foreignObject была доступна для просмотра с использованием семантических возможностей, таких как заголовки, вам, вероятно, придется использовать role=document, от чего многие члены сообщества, несомненно, предупредят вас, потому что это сложно. Мне удалось заставить role=document нормально работать в HTML, но еще не интегрировал его с SVG. Я еще не знаю, будет ли он хорошо работать с графическим модулем WAI-ARIA роли.

person brennanyoung    schedule 21.01.2020
comment
Я буду считать ответ Грэма ответом - спасибо Грэму; дерево W3C выглядит действительно полезным (хотя и немного менее красивым) как способ создания удобной для вслепую разветвленной структуры вопросов / ответов. - person Paddy UK; 27.01.2020

К сожалению, в имеющемся у вас примере это будет очень сложно реализовать (не часть маркировки, а доступность в целом из-за структуры документа).

Первое, что вам нужно сделать, это исправить порядок DOM SVG - первый узел, на который вы попадаете, - это «нет», что сбивает с толку, и исправить порядок DOM намного проще, чем пытаться управлять tabindex.

Следующим шагом является то, что вам нужно показать, что активация элемента (например, «да») приводит к загрузке дополнительных опций.

Для этого я бы следовал правилам сворачиваемого контента - этот пример аккордеона должен помочь вам понять, как правильно использовать aria-expanded и aria-controls. (но используйте его только для понимания этих концепций, это неправильное решение вашей проблемы.)

Затем вам нужно подумать о том, чтобы сообщить пользователю, какие варианты были ему теперь представлены. Самый простой способ сделать это - заключить SVGs в <ul>, так как тогда программа чтения с экрана сообщит им, из скольких элементов можно выбрать (в развернутом разделе).

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

Также посмотрите в этом проводнике файлов пример древовидного представления, который похож на то, что при правильном вложении вам не нужно слишком беспокоиться о маркировке. (поскольку вы можете просто использовать свойство <title> вашего SVGs в качестве содержимого, если вы обнаружите, что простой текст читается неправильно).

В приведенных выше примерах вы заметите, что текст «родительского узла» фактически содержится в <li role="treeitem">, так что, когда вы выбираете подпункт, он автоматически считывает и родительский, и выбранный элемент.

Попытка сделать все вышеперечисленное с помощью только SVG вызовет у вас многочисленные головные боли с обходными путями (например, вы можете использовать _ 9_ с несколькими идентификаторами дочерних элементов, чтобы достичь того, о чем вы первоначально просили, но затем у вас есть много проблем с ремонтопригодностью), поэтому я бы рекомендовал попробовать скопировать treeview структурируйте и сохраняйте ваши SVG-файлы простыми.

Последним преимуществом метода treeview является то, что пользователи будут знакомы с тем, как управлять древовидным представлением (клавиши со стрелкой и пробел для развертывания / свертывания), поэтому вам не нужно попробуйте научить их, какие элементы управления использовать.

Пример

Немного сложно читать, но, надеюсь, он даст вам представление о том, как должна выглядеть ваша конечная структура. Я удалил множество атрибутов позиционирования и т. Д., Чтобы упростить чтение.

<h3 id="tree_lbl">
  Decision Tree
</h3>
<ul role="tree" aria-labelledby="tree_lbl">
  <li role="treeitem" aria-expanded="false">
      <g class="node">
        <foreignObject tabindex="0" focusable="true" class="nodestyle">Is this a decision tree?</foreignObject>
      </g>
    <ul role="group">
      <li role="treeitem" aria-expanded="false">
        <g class="node">
          <foreignObject tabindex="0" focusable="true" class="nodestyle">Yes</foreignObject>
        </g>
        <ul role="group">
          <li role="treeitem">
            <g class="node"><foreignObject tabindex="0" focusable="true" class="nodestyle">A</foreignObject></g>
          </li>
          <li role="treeitem">
            <g class="node">
              <foreignObject tabindex="0" focusable="true" class="nodestyle">B</foreignObject>
            </g>
          </li>
        </ul>
      </li>
      <li role="treeitem" aria-expanded="false">
        <span>
          <g class="node">
              <foreignObject tabindex="0" focusable="true" class="nodestyle">No</foreignObject></g>
        </span>
        <ul role="group">
          <li role="treeitem" class="doc">
            <g class="node">
              <foreignObject tabindex="0" focusable="true" class="nodestyle">A1</foreignObject>
            </g>
          </li>
          <li role="treeitem" class="doc">
            <g class="node">
              <foreignObject tabindex="0" focusable="true" class="nodestyle">B1</foreignObject>
            </g>
          </li>
        </ul>
      </li>
    </ul>
  </li>
  </ul>
person Graham Ritchie    schedule 21.01.2020