Как указать подпись вне элемента рисунка

У меня есть ситуация, когда мне нужно физически отделить подпись от связанного рисунка, например, такую ​​разметку:

      <figure>
  <img src="…" alt="…"/>
</figure>

…later in the code…

<figcaption>
  Caption text
<figcaption>

Это семантически неверно (существуют существующие вопросы SO, касающиеся этого ), и вызывает ошибку проверки. Учитывая это, мне интересно, как лучше всего это представить (с учетом разметки и доступности).

В идеале должен быть какой-то атрибут (например, label элементы for атрибут), который позволит вам связать figcaption с figure. В настоящее время я использую aria-describedby атрибут (см. ниже), но я не уверен, что это так.

      <figure aria-describedby="caption">
  <img src="…" alt="…"/>
</figure>

…later in the code…

<div id="caption">
  Caption text
<div>

1 ответ

Есть несколько способов приблизиться к этому: либо добавление роли и использование, либо с помощью JavaScript.

Метод 1 - только HTML

В aria-labelledby атрибут распознается только в элементах управления формой (например, кнопки, поля ввода, флажки и т. д.) или в элементах, которые имеют roleприсвоенный атрибут. Без любого из этих условий вычисление доступного имени не будет вычисляться для элемента.

      <figure role="region" aria-labelledby="caption-text">
    <img src="/images/logo.png" alt="your image alt text" />
</figure>

<p>…later in the code…</p>

<div id="caption-text">Caption text</div>

В моем тестировании на NVDA / Chrome это работает, пока altатрибут на изображении не пуст. Я настоятельно рекомендую протестировать это с использованием разных браузеров и программ чтения с экрана перед развертыванием в производственной среде по той причине, что это, по сути, label на неинтерактивном элементе.

Метод 2 - JavaScript и CSS

Этот метод больше соответствует вашему исходному вопросу. Создает визуальный figcaption элемент как дочерний элемент figure элемент.

      <style>
    .sr-only {
        clip: rect(1px, 1px, 1px, 1px);
        clip-path: inset(50%);
        height: 1px;
        width: 1px;
        margin: -1px;
        overflow: hidden;
        padding: 0;
        position: absolute;
    }
</style>

<figure id="fig">
    <img src="/images/logo.png" alt="" />
</figure>

<p>…later in the code…</p>

<div id="caption-text" aria-hidden="true">Caption text</div>

<script>
    document.addEventListener("DOMContentLoaded", () => {
        
        // create a figcaption element
        const caption = document.createElement("figcaption")
        
        // get innerText from div#caption-text and add to new figcaption element
        caption.innerText = document.getElementById("caption-text").innerText
        
        // assign a class to visually hide
        caption.className = "sr-only"

        // append figcaption to the figure element
        document.getElementById("fig").appendChild(caption)
    });
</script>
Другие вопросы по тегам